From 412b25d9711849e13b4392b88ff935826fda7fb3 Mon Sep 17 00:00:00 2001 From: James Housley Date: Mon, 28 May 2007 17:56:08 +0000 Subject: [PATCH] Initially the libssh2 code was indented with tabs of 4 spaces. Some of the recent commits converted the tabs to 4 spaces, which matched the initial indent size. Other commits converted the tabs to 8 spaces, this didn't match. All the code has been converted to 4 space indents. No changes to line lengths or actual code was performed. This is in preperation to my up coming non-blocking work so my commits should only be code changes and line lengths in the code I am working on. --- include/libssh2.h | 354 +++--- include/libssh2_publickey.h | 42 +- include/libssh2_sftp.h | 224 ++-- src/channel.c | 1936 ++++++++++++++++----------------- src/comp.c | 344 +++--- src/crypt.c | 254 ++--- src/hostkey.c | 394 +++---- src/kex.c | 2052 +++++++++++++++++------------------ src/libgcrypt.c | 798 +++++++------- src/libgcrypt.h | 112 +- src/libssh2_priv.h | 566 +++++----- src/mac.c | 240 ++-- src/misc.c | 174 +-- src/openssl.c | 371 ++++--- src/openssl.h | 110 +- src/packet.c | 1340 +++++++++++------------ src/pem.c | 286 ++--- src/publickey.c | 1032 +++++++++--------- src/scp.c | 644 +++++------ src/session.c | 1306 +++++++++++----------- src/sftp.c | 1572 +++++++++++++-------------- src/transport.c | 1126 +++++++++---------- src/userauth.c | 1218 ++++++++++----------- 23 files changed, 8247 insertions(+), 8248 deletions(-) diff --git a/include/libssh2.h b/include/libssh2.h index 2871f3c..e4f186f 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -75,15 +75,15 @@ typedef unsigned long long libssh2_uint64_t; typedef long long libssh2_int64_t; #endif -#define LIBSSH2_VERSION "0.15-CVS" -#define LIBSSH2_APINO 200507211326 +#define LIBSSH2_VERSION "0.15-CVS" +#define LIBSSH2_APINO 200507211326 /* Part of every banner, user specified or not */ -#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION +#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION /* We *could* add a comment here if we so chose */ -#define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER -#define LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF LIBSSH2_SSH_DEFAULT_BANNER "\r\n" +#define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER +#define LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF LIBSSH2_SSH_DEFAULT_BANNER "\r\n" /* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1 */ #define LIBSSH2_DH_GEX_MINGROUP 1024 @@ -91,177 +91,177 @@ typedef long long libssh2_int64_t; #define LIBSSH2_DH_GEX_MAXGROUP 2048 /* Defaults for pty requests */ -#define LIBSSH2_TERM_WIDTH 80 -#define LIBSSH2_TERM_HEIGHT 24 -#define LIBSSH2_TERM_WIDTH_PX 0 -#define LIBSSH2_TERM_HEIGHT_PX 0 +#define LIBSSH2_TERM_WIDTH 80 +#define LIBSSH2_TERM_HEIGHT 24 +#define LIBSSH2_TERM_WIDTH_PX 0 +#define LIBSSH2_TERM_HEIGHT_PX 0 /* 1/4 second */ -#define LIBSSH2_SOCKET_POLL_UDELAY 250000 +#define LIBSSH2_SOCKET_POLL_UDELAY 250000 /* 0.25 * 120 == 30 seconds */ -#define LIBSSH2_SOCKET_POLL_MAXLOOPS 120 +#define LIBSSH2_SOCKET_POLL_MAXLOOPS 120 /* Maximum size to allow a payload to compress to, plays it safe by falling short of spec limits */ -#define LIBSSH2_PACKET_MAXCOMP 32000 +#define LIBSSH2_PACKET_MAXCOMP 32000 /* Maximum size to allow a payload to deccompress to, plays it safe by allowing more than spec requires */ -#define LIBSSH2_PACKET_MAXDECOMP 40000 +#define LIBSSH2_PACKET_MAXDECOMP 40000 /* Maximum size for an inbound compressed payload, plays it safe by overshooting spec limits */ -#define LIBSSH2_PACKET_MAXPAYLOAD 40000 +#define LIBSSH2_PACKET_MAXPAYLOAD 40000 /* Malloc callbacks */ -#define LIBSSH2_ALLOC_FUNC(name) void *name(size_t count, void **abstract) -#define LIBSSH2_REALLOC_FUNC(name) void *name(void *ptr, size_t count, void **abstract) -#define LIBSSH2_FREE_FUNC(name) void name(void *ptr, void **abstract) +#define LIBSSH2_ALLOC_FUNC(name) void *name(size_t count, void **abstract) +#define LIBSSH2_REALLOC_FUNC(name) void *name(void *ptr, size_t count, void **abstract) +#define LIBSSH2_FREE_FUNC(name) void name(void *ptr, void **abstract) typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT { - char* text; - unsigned int length; - unsigned char echo; + char* text; + unsigned int length; + unsigned char echo; } LIBSSH2_USERAUTH_KBDINT_PROMPT; typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE { - char* text; - unsigned int length; + char* text; + unsigned int length; } LIBSSH2_USERAUTH_KBDINT_RESPONSE; /* 'keyboard-interactive' authentication callback */ #define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) void name_(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract) /* Callbacks for special SSH packets */ -#define LIBSSH2_IGNORE_FUNC(name) void name(LIBSSH2_SESSION *session, const char *message, int message_len, void **abstract) -#define LIBSSH2_DEBUG_FUNC(name) void name(LIBSSH2_SESSION *session, int always_display, const char *message, int message_len, const char *language, int language_len,void **abstract) -#define LIBSSH2_DISCONNECT_FUNC(name) void name(LIBSSH2_SESSION *session, int reason, const char *message, int message_len, const char *language, int language_len, void **abstract) -#define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, void **abstract) -#define LIBSSH2_MACERROR_FUNC(name) int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, void **abstract) -#define LIBSSH2_X11_OPEN_FUNC(name) void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, const char *shost, int sport, void **abstract) +#define LIBSSH2_IGNORE_FUNC(name) void name(LIBSSH2_SESSION *session, const char *message, int message_len, void **abstract) +#define LIBSSH2_DEBUG_FUNC(name) void name(LIBSSH2_SESSION *session, int always_display, const char *message, int message_len, const char *language, int language_len,void **abstract) +#define LIBSSH2_DISCONNECT_FUNC(name) void name(LIBSSH2_SESSION *session, int reason, const char *message, int message_len, const char *language, int language_len, void **abstract) +#define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, void **abstract) +#define LIBSSH2_MACERROR_FUNC(name) int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, void **abstract) +#define LIBSSH2_X11_OPEN_FUNC(name) void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, const char *shost, int sport, void **abstract) -#define LIBSSH2_CHANNEL_CLOSE_FUNC(name) void name(LIBSSH2_SESSION *session, void **session_abstract, LIBSSH2_CHANNEL *channel, void **channel_abstract) +#define LIBSSH2_CHANNEL_CLOSE_FUNC(name) void name(LIBSSH2_SESSION *session, void **session_abstract, LIBSSH2_CHANNEL *channel, void **channel_abstract) /* libssh2_session_callback_set() constants */ -#define LIBSSH2_CALLBACK_IGNORE 0 -#define LIBSSH2_CALLBACK_DEBUG 1 -#define LIBSSH2_CALLBACK_DISCONNECT 2 -#define LIBSSH2_CALLBACK_MACERROR 3 -#define LIBSSH2_CALLBACK_X11 4 +#define LIBSSH2_CALLBACK_IGNORE 0 +#define LIBSSH2_CALLBACK_DEBUG 1 +#define LIBSSH2_CALLBACK_DISCONNECT 2 +#define LIBSSH2_CALLBACK_MACERROR 3 +#define LIBSSH2_CALLBACK_X11 4 /* libssh2_session_method_pref() constants */ -#define LIBSSH2_METHOD_KEX 0 -#define LIBSSH2_METHOD_HOSTKEY 1 -#define LIBSSH2_METHOD_CRYPT_CS 2 -#define LIBSSH2_METHOD_CRYPT_SC 3 -#define LIBSSH2_METHOD_MAC_CS 4 -#define LIBSSH2_METHOD_MAC_SC 5 -#define LIBSSH2_METHOD_COMP_CS 6 -#define LIBSSH2_METHOD_COMP_SC 7 -#define LIBSSH2_METHOD_LANG_CS 8 -#define LIBSSH2_METHOD_LANG_SC 9 +#define LIBSSH2_METHOD_KEX 0 +#define LIBSSH2_METHOD_HOSTKEY 1 +#define LIBSSH2_METHOD_CRYPT_CS 2 +#define LIBSSH2_METHOD_CRYPT_SC 3 +#define LIBSSH2_METHOD_MAC_CS 4 +#define LIBSSH2_METHOD_MAC_SC 5 +#define LIBSSH2_METHOD_COMP_CS 6 +#define LIBSSH2_METHOD_COMP_SC 7 +#define LIBSSH2_METHOD_LANG_CS 8 +#define LIBSSH2_METHOD_LANG_SC 9 /* session.flags bits */ -#define LIBSSH2_FLAG_SIGPIPE 0x00000001 +#define LIBSSH2_FLAG_SIGPIPE 0x00000001 -typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; -typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL; -typedef struct _LIBSSH2_LISTENER LIBSSH2_LISTENER; +typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; +typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL; +typedef struct _LIBSSH2_LISTENER LIBSSH2_LISTENER; typedef struct _LIBSSH2_POLLFD { - unsigned char type; /* LIBSSH2_POLLFD_* below */ + unsigned char type; /* LIBSSH2_POLLFD_* below */ - union { - int socket; /* File descriptors -- examined with system select() call */ - LIBSSH2_CHANNEL *channel; /* Examined by checking internal state */ - LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound connections waiting to be accepted? */ - } fd; + union { + int socket; /* File descriptors -- examined with system select() call */ + LIBSSH2_CHANNEL *channel; /* Examined by checking internal state */ + LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound connections waiting to be accepted? */ + } fd; - unsigned long events; /* Requested Events */ - unsigned long revents; /* Returned Events */ + unsigned long events; /* Requested Events */ + unsigned long revents; /* Returned Events */ } LIBSSH2_POLLFD; /* Poll FD Descriptor Types */ -#define LIBSSH2_POLLFD_SOCKET 1 -#define LIBSSH2_POLLFD_CHANNEL 2 -#define LIBSSH2_POLLFD_LISTENER 3 +#define LIBSSH2_POLLFD_SOCKET 1 +#define LIBSSH2_POLLFD_CHANNEL 2 +#define LIBSSH2_POLLFD_LISTENER 3 /* Note: Win32 Doesn't actually have a poll() implementation, so some of these values are faked with select() data */ /* Poll FD events/revents -- Match sys/poll.h where possible */ -#define LIBSSH2_POLLFD_POLLIN 0x0001 /* Data available to be read or connection available -- All */ -#define LIBSSH2_POLLFD_POLLPRI 0x0002 /* Priority data available to be read -- Socket only */ -#define LIBSSH2_POLLFD_POLLEXT 0x0002 /* Extended data available to be read -- Channel only */ -#define LIBSSH2_POLLFD_POLLOUT 0x0004 /* Can may be written -- Socket/Channel */ +#define LIBSSH2_POLLFD_POLLIN 0x0001 /* Data available to be read or connection available -- All */ +#define LIBSSH2_POLLFD_POLLPRI 0x0002 /* Priority data available to be read -- Socket only */ +#define LIBSSH2_POLLFD_POLLEXT 0x0002 /* Extended data available to be read -- Channel only */ +#define LIBSSH2_POLLFD_POLLOUT 0x0004 /* Can may be written -- Socket/Channel */ /* revents only */ -#define LIBSSH2_POLLFD_POLLERR 0x0008 /* Error Condition -- Socket */ -#define LIBSSH2_POLLFD_POLLHUP 0x0010 /* HangUp/EOF -- Socket */ -#define LIBSSH2_POLLFD_SESSION_CLOSED 0x0010 /* Session Disconnect */ -#define LIBSSH2_POLLFD_POLLNVAL 0x0020 /* Invalid request -- Socket Only */ -#define LIBSSH2_POLLFD_POLLEX 0x0040 /* Exception Condition -- Socket/Win32 */ -#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */ -#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */ +#define LIBSSH2_POLLFD_POLLERR 0x0008 /* Error Condition -- Socket */ +#define LIBSSH2_POLLFD_POLLHUP 0x0010 /* HangUp/EOF -- Socket */ +#define LIBSSH2_POLLFD_SESSION_CLOSED 0x0010 /* Session Disconnect */ +#define LIBSSH2_POLLFD_POLLNVAL 0x0020 /* Invalid request -- Socket Only */ +#define LIBSSH2_POLLFD_POLLEX 0x0040 /* Exception Condition -- Socket/Win32 */ +#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */ +#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */ /* Hash Types */ -#define LIBSSH2_HOSTKEY_HASH_MD5 1 -#define LIBSSH2_HOSTKEY_HASH_SHA1 2 +#define LIBSSH2_HOSTKEY_HASH_MD5 1 +#define LIBSSH2_HOSTKEY_HASH_SHA1 2 /* Disconnect Codes (defined by SSH protocol) */ -#define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 -#define SSH_DISCONNECT_PROTOCOL_ERROR 2 -#define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3 -#define SSH_DISCONNECT_RESERVED 4 -#define SSH_DISCONNECT_MAC_ERROR 5 -#define SSH_DISCONNECT_COMPRESSION_ERROR 6 -#define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7 -#define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 -#define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 -#define SSH_DISCONNECT_CONNECTION_LOST 10 -#define SSH_DISCONNECT_BY_APPLICATION 11 -#define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12 -#define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13 -#define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 -#define SSH_DISCONNECT_ILLEGAL_USER_NAME 15 +#define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 +#define SSH_DISCONNECT_PROTOCOL_ERROR 2 +#define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3 +#define SSH_DISCONNECT_RESERVED 4 +#define SSH_DISCONNECT_MAC_ERROR 5 +#define SSH_DISCONNECT_COMPRESSION_ERROR 6 +#define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7 +#define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 +#define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 +#define SSH_DISCONNECT_CONNECTION_LOST 10 +#define SSH_DISCONNECT_BY_APPLICATION 11 +#define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12 +#define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13 +#define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 +#define SSH_DISCONNECT_ILLEGAL_USER_NAME 15 /* Error Codes (defined by libssh2) */ -#define LIBSSH2_ERROR_SOCKET_NONE -1 -#define LIBSSH2_ERROR_BANNER_NONE -2 -#define LIBSSH2_ERROR_BANNER_SEND -3 -#define LIBSSH2_ERROR_INVALID_MAC -4 -#define LIBSSH2_ERROR_KEX_FAILURE -5 -#define LIBSSH2_ERROR_ALLOC -6 -#define LIBSSH2_ERROR_SOCKET_SEND -7 -#define LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE -8 -#define LIBSSH2_ERROR_TIMEOUT -9 -#define LIBSSH2_ERROR_HOSTKEY_INIT -10 -#define LIBSSH2_ERROR_HOSTKEY_SIGN -11 -#define LIBSSH2_ERROR_DECRYPT -12 -#define LIBSSH2_ERROR_SOCKET_DISCONNECT -13 -#define LIBSSH2_ERROR_PROTO -14 -#define LIBSSH2_ERROR_PASSWORD_EXPIRED -15 -#define LIBSSH2_ERROR_FILE -16 -#define LIBSSH2_ERROR_METHOD_NONE -17 -#define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED -18 -#define LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED -19 -#define LIBSSH2_ERROR_CHANNEL_OUTOFORDER -20 -#define LIBSSH2_ERROR_CHANNEL_FAILURE -21 -#define LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED -22 -#define LIBSSH2_ERROR_CHANNEL_UNKNOWN -23 -#define LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED -24 -#define LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED -25 -#define LIBSSH2_ERROR_CHANNEL_CLOSED -26 -#define LIBSSH2_ERROR_CHANNEL_EOF_SENT -27 -#define LIBSSH2_ERROR_SCP_PROTOCOL -28 -#define LIBSSH2_ERROR_ZLIB -29 -#define LIBSSH2_ERROR_SOCKET_TIMEOUT -30 -#define LIBSSH2_ERROR_SFTP_PROTOCOL -31 -#define LIBSSH2_ERROR_REQUEST_DENIED -32 -#define LIBSSH2_ERROR_METHOD_NOT_SUPPORTED -33 -#define LIBSSH2_ERROR_INVAL -34 -#define LIBSSH2_ERROR_INVALID_POLL_TYPE -35 -#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36 +#define LIBSSH2_ERROR_SOCKET_NONE -1 +#define LIBSSH2_ERROR_BANNER_NONE -2 +#define LIBSSH2_ERROR_BANNER_SEND -3 +#define LIBSSH2_ERROR_INVALID_MAC -4 +#define LIBSSH2_ERROR_KEX_FAILURE -5 +#define LIBSSH2_ERROR_ALLOC -6 +#define LIBSSH2_ERROR_SOCKET_SEND -7 +#define LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE -8 +#define LIBSSH2_ERROR_TIMEOUT -9 +#define LIBSSH2_ERROR_HOSTKEY_INIT -10 +#define LIBSSH2_ERROR_HOSTKEY_SIGN -11 +#define LIBSSH2_ERROR_DECRYPT -12 +#define LIBSSH2_ERROR_SOCKET_DISCONNECT -13 +#define LIBSSH2_ERROR_PROTO -14 +#define LIBSSH2_ERROR_PASSWORD_EXPIRED -15 +#define LIBSSH2_ERROR_FILE -16 +#define LIBSSH2_ERROR_METHOD_NONE -17 +#define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED -18 +#define LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED -19 +#define LIBSSH2_ERROR_CHANNEL_OUTOFORDER -20 +#define LIBSSH2_ERROR_CHANNEL_FAILURE -21 +#define LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED -22 +#define LIBSSH2_ERROR_CHANNEL_UNKNOWN -23 +#define LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED -24 +#define LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED -25 +#define LIBSSH2_ERROR_CHANNEL_CLOSED -26 +#define LIBSSH2_ERROR_CHANNEL_EOF_SENT -27 +#define LIBSSH2_ERROR_SCP_PROTOCOL -28 +#define LIBSSH2_ERROR_ZLIB -29 +#define LIBSSH2_ERROR_SOCKET_TIMEOUT -30 +#define LIBSSH2_ERROR_SFTP_PROTOCOL -31 +#define LIBSSH2_ERROR_REQUEST_DENIED -32 +#define LIBSSH2_ERROR_METHOD_NOT_SUPPORTED -33 +#define LIBSSH2_ERROR_INVAL -34 +#define LIBSSH2_ERROR_INVALID_POLL_TYPE -35 +#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36 /* Session API */ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), LIBSSH2_FREE_FUNC((*my_free)), LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract); -#define libssh2_session_init() libssh2_session_init_ex(NULL, NULL, NULL, NULL) +#define libssh2_session_init() libssh2_session_init_ex(NULL, NULL, NULL, NULL) LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session); LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback); @@ -269,7 +269,7 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner) LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket); LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang); -#define libssh2_session_disconnect(session, description) libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, (description), "") +#define libssh2_session_disconnect(session, description) libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, (description), "") LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session); LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type); @@ -284,20 +284,20 @@ LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int val LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len); LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *password, unsigned int password_len, LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))); -#define libssh2_userauth_password(session, username, password) libssh2_userauth_password_ex((session), (username), strlen(username), (password), strlen(password), NULL) +#define libssh2_userauth_password(session, username, password) libssh2_userauth_password_ex((session), (username), strlen(username), (password), strlen(password), NULL) LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, - const char *publickey, const char *privatekey, - const char *passphrase); -#define libssh2_userauth_publickey_fromfile(session, username, publickey, privatekey, passphrase) \ - libssh2_userauth_publickey_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase)) + const char *publickey, const char *privatekey, + const char *passphrase); +#define libssh2_userauth_publickey_fromfile(session, username, publickey, privatekey, passphrase) \ + libssh2_userauth_publickey_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase)) LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, - const char *publickey, const char *privatekey, - const char *passphrase, - const char *hostname, unsigned int hostname_len, - const char *local_username, unsigned int local_username_len); -#define libssh2_userauth_hostbased_fromfile(session, username, publickey, privatekey, passphrase, hostname) \ - libssh2_userauth_hostbased_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase), (hostname), strlen(hostname), (username), strlen(username)) + const char *publickey, const char *privatekey, + const char *passphrase, + const char *hostname, unsigned int hostname_len, + const char *local_username, unsigned int local_username_len); +#define libssh2_userauth_hostbased_fromfile(session, username, publickey, privatekey, passphrase, hostname) \ + libssh2_userauth_hostbased_fromfile_ex((session), (username), strlen(username), (publickey), (privatekey), (passphrase), (hostname), strlen(hostname), (username), strlen(username)) /* * response_callback is provided with filled by library prompts array, @@ -306,32 +306,32 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, * after callback return, but before subsequent callback invokation. */ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session, const char *username, unsigned int username_len, - LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))); + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))); #define libssh2_userauth_keyboard_interactive(session, username, response_callback) \ libssh2_userauth_keyboard_interactive_ex((session), (username), strlen(username), (response_callback)) LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout); /* Channel API */ -#define LIBSSH2_CHANNEL_WINDOW_DEFAULT 65536 -#define LIBSSH2_CHANNEL_PACKET_DEFAULT 16384 -#define LIBSSH2_CHANNEL_MINADJUST 1024 +#define LIBSSH2_CHANNEL_WINDOW_DEFAULT 65536 +#define LIBSSH2_CHANNEL_PACKET_DEFAULT 16384 +#define LIBSSH2_CHANNEL_MINADJUST 1024 /* Extended Data Handling */ -#define LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL 0 -#define LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE 1 -#define LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE 2 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL 0 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE 1 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE 2 #define SSH_EXTENDED_DATA_STDERR 1 LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsigned int channel_type_len, unsigned int window_size, unsigned int packet_size, const char *message, unsigned int message_len); -#define libssh2_channel_open_session(session) libssh2_channel_open_ex((session), "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0) +#define libssh2_channel_open_session(session) libssh2_channel_open_ex((session), "session", sizeof("session") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0) LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport); -#define libssh2_channel_direct_tcpip(session, host, port) libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22) +#define libssh2_channel_direct_tcpip(session, host, port) libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22) LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, int port, int *bound_port, int queue_maxsize); -#define libssh2_channel_forward_listen(session, port) libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16) +#define libssh2_channel_forward_listen(session, port) libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16) LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); @@ -341,22 +341,22 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varnam #define libssh2_channel_setenv(channel, varname, value) libssh2_channel_setenv_ex((channel), (varname), strlen(varname), (value), strlen(value)) LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, const char *modes, unsigned int modes_len, int width, int height, int width_px, int height_px); -#define libssh2_channel_request_pty(channel, term) libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX) +#define libssh2_channel_request_pty(channel, term) libssh2_channel_request_pty_ex((channel), (term), strlen(term), NULL, 0, LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX) LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number); -#define libssh2_channel_x11_req(channel, screen_number) libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number)) +#define libssh2_channel_x11_req(channel, screen_number) libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number)) LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, unsigned int request_len, const char *message, unsigned int message_len); -#define libssh2_channel_shell(channel) libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, NULL, 0) -#define libssh2_channel_exec(channel, command) libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command)) -#define libssh2_channel_subsystem(channel, subsystem) libssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem)) +#define libssh2_channel_shell(channel) libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, NULL, 0) +#define libssh2_channel_exec(channel, command) libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, (command), strlen(command)) +#define libssh2_channel_subsystem(channel, subsystem) libssh2_channel_process_startup((channel), "subsystem", sizeof("subsystem") - 1, (subsystem), strlen(subsystem)) LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, - int stream_id, char *buf, - size_t buflen); + int stream_id, char *buf, + size_t buflen); LIBSSH2_API int libssh2_channel_readnb_ex(LIBSSH2_CHANNEL *channel, - int stream_id, char *buf, - size_t buflen); + int stream_id, char *buf, + size_t buflen); /* This is a public error code from libssh2_channel_read() that is returned when it would otherwise block. */ @@ -364,32 +364,32 @@ LIBSSH2_API int libssh2_channel_readnb_ex(LIBSSH2_CHANNEL *channel, #define libssh2_channel_read(channel, buf, buflen) \ libssh2_channel_read_ex((channel), 0, (buf), (buflen)) -#define libssh2_channel_read_stderr(channel, buf, buflen) libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) +#define libssh2_channel_read_stderr(channel, buf, buflen) libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) #define libssh2_channel_readnb(channel, buf, buflen) \ libssh2_channel_readnb_ex((channel), 0, (buf), (buflen)) LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended); LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, unsigned long *read_avail, unsigned long *window_size_initial); -#define libssh2_channel_window_read(channel) libssh2_channel_window_read_ex((channel), NULL, NULL) +#define libssh2_channel_window_read(channel) libssh2_channel_window_read_ex((channel), NULL, NULL) LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force); LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, - int stream_id, const char *buf, - size_t buflen); + int stream_id, const char *buf, + size_t buflen); LIBSSH2_API int libssh2_channel_writenb_ex(LIBSSH2_CHANNEL *channel, - int stream_id, const char *buf, - size_t buflen); + int stream_id, const char *buf, + size_t buflen); #define libssh2_channel_write(channel, buf, buflen) \ libssh2_channel_write_ex((channel), 0, (buf), (buflen)) #define libssh2_channel_writenb(channel, buf, buflen) \ libssh2_channel_writenb_ex((channel), 0, (buf), (buflen)) -#define libssh2_channel_write_stderr(channel, buf, buflen) libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) +#define libssh2_channel_write_stderr(channel, buf, buflen) libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial); -#define libssh2_channel_window_write(channel) libssh2_channel_window_write_ex((channel), NULL) +#define libssh2_channel_window_write(channel) libssh2_channel_window_write_ex((channel), NULL) LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking); LIBSSH2_API int libssh2_channel_get_blocking(LIBSSH2_CHANNEL *channel); @@ -400,13 +400,13 @@ LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, * if LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read (FIFO) from the standard data channel */ /* DEPRECATED */ -#define libssh2_channel_ignore_extended_data(channel, ignore) libssh2_channel_handle_extended_data((channel), (ignore) ? LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL ) +#define libssh2_channel_ignore_extended_data(channel, ignore) libssh2_channel_handle_extended_data((channel), (ignore) ? LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL ) -#define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA -1 -#define LIBSSH2_CHANNEL_FLUSH_ALL -2 +#define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA -1 +#define LIBSSH2_CHANNEL_FLUSH_ALL -2 LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid); -#define libssh2_channel_flush(channel) libssh2_channel_flush_ex((channel), 0) -#define libssh2_channel_flush_stderr(channel) libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR) +#define libssh2_channel_flush(channel) libssh2_channel_flush_ex((channel), 0) +#define libssh2_channel_flush_stderr(channel) libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR) LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel); LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel); @@ -417,7 +417,7 @@ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel); LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb); LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime); -#define libssh2_scp_send(session, path, mode, size) libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0) +#define libssh2_scp_send(session, path, mode, size) libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0) LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, unsigned int *dest_len, const char *src, unsigned int src_len); @@ -426,14 +426,14 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, uns enabled */ LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask); -#define LIBSSH2_TRACE_TRANS (1<<1) -#define LIBSSH2_TRACE_KEX (1<<2) -#define LIBSSH2_TRACE_AUTH (1<<3) -#define LIBSSH2_TRACE_CONN (1<<4) -#define LIBSSH2_TRACE_SCP (1<<5) -#define LIBSSH2_TRACE_SFTP (1<<6) -#define LIBSSH2_TRACE_ERROR (1<<7) -#define LIBSSH2_TRACE_PUBLICKEY (1<<8) +#define LIBSSH2_TRACE_TRANS (1<<1) +#define LIBSSH2_TRACE_KEX (1<<2) +#define LIBSSH2_TRACE_AUTH (1<<3) +#define LIBSSH2_TRACE_CONN (1<<4) +#define LIBSSH2_TRACE_SCP (1<<5) +#define LIBSSH2_TRACE_SFTP (1<<6) +#define LIBSSH2_TRACE_ERROR (1<<7) +#define LIBSSH2_TRACE_PUBLICKEY (1<<8) #ifdef __cplusplus } /* extern "C" */ diff --git a/include/libssh2_publickey.h b/include/libssh2_publickey.h index 1f87745..92fc5a4 100644 --- a/include/libssh2_publickey.h +++ b/include/libssh2_publickey.h @@ -44,32 +44,32 @@ */ #ifndef LIBSSH2_PUBLICKEY_H -#define LIBSSH2_PUBLICKEY_H 1 +#define LIBSSH2_PUBLICKEY_H 1 -typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY; +typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY; typedef struct _libssh2_publickey_attribute { - const char *name; - unsigned long name_len; - const char *value; - unsigned long value_len; - char mandatory; + const char *name; + unsigned long name_len; + const char *value; + unsigned long value_len; + char mandatory; } libssh2_publickey_attribute; typedef struct _libssh2_publickey_list { - unsigned char *packet; /* For freeing */ + unsigned char *packet; /* For freeing */ - const unsigned char *name; - unsigned long name_len; - const unsigned char *blob; - unsigned long blob_len; - unsigned long num_attrs; - libssh2_publickey_attribute *attrs; /* free me */ + const unsigned char *name; + unsigned long name_len; + const unsigned char *blob; + unsigned long blob_len; + unsigned long num_attrs; + libssh2_publickey_attribute *attrs; /* free me */ } libssh2_publickey_list; /* Generally use the first macro here, but if both name and value are string literals, you can use _fast() to take advantage of preprocessing */ -#define libssh2_publickey_attribute(name, value, mandatory) { (name), strlen(name), (value), strlen(value), (mandatory) }, -#define libssh2_publickey_attribute_fast(name, value, mandatory) { (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) }, +#define libssh2_publickey_attribute(name, value, mandatory) { (name), strlen(name), (value), strlen(value), (mandatory) }, +#define libssh2_publickey_attribute_fast(name, value, mandatory) { (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) }, #ifdef __cplusplus extern "C" { @@ -79,15 +79,15 @@ extern "C" { LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session); LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, - const unsigned char *blob, unsigned long blob_len, char overwrite, - unsigned long num_attrs, const libssh2_publickey_attribute attrs[]); + const unsigned char *blob, unsigned long blob_len, char overwrite, + unsigned long num_attrs, const libssh2_publickey_attribute attrs[]); #define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, num_attrs, attrs) \ - libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), (overwrite), (num_attrs), (attrs)) + libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), (overwrite), (num_attrs), (attrs)) LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, - const unsigned char *blob, unsigned long blob_len); + const unsigned char *blob, unsigned long blob_len); #define libssh2_publickey_remove(pkey, name, blob, blob_len) \ - libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len)) + libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len)) LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, libssh2_publickey_list **pkey_list); LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_publickey_list *pkey_list); diff --git a/include/libssh2_sftp.h b/include/libssh2_sftp.h index fb4417b..5587da9 100644 --- a/include/libssh2_sftp.h +++ b/include/libssh2_sftp.h @@ -51,61 +51,61 @@ extern "C" { * * Let's start with Version 3 (The version found in OpenSSH) and go from there */ -#define LIBSSH2_SFTP_VERSION 3 -#define LIBSSH2_SFTP_PACKET_MAXLEN 40000 +#define LIBSSH2_SFTP_VERSION 3 +#define LIBSSH2_SFTP_PACKET_MAXLEN 40000 -typedef struct _LIBSSH2_SFTP LIBSSH2_SFTP; -typedef struct _LIBSSH2_SFTP_HANDLE LIBSSH2_SFTP_HANDLE; -typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES; +typedef struct _LIBSSH2_SFTP LIBSSH2_SFTP; +typedef struct _LIBSSH2_SFTP_HANDLE LIBSSH2_SFTP_HANDLE; +typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES; /* Flags for open_ex() */ -#define LIBSSH2_SFTP_OPENFILE 0 -#define LIBSSH2_SFTP_OPENDIR 1 +#define LIBSSH2_SFTP_OPENFILE 0 +#define LIBSSH2_SFTP_OPENDIR 1 /* Flags for rename_ex() */ -#define LIBSSH2_SFTP_RENAME_OVERWRITE 0x00000001 -#define LIBSSH2_SFTP_RENAME_ATOMIC 0x00000002 -#define LIBSSH2_SFTP_RENAME_NATIVE 0x00000004 +#define LIBSSH2_SFTP_RENAME_OVERWRITE 0x00000001 +#define LIBSSH2_SFTP_RENAME_ATOMIC 0x00000002 +#define LIBSSH2_SFTP_RENAME_NATIVE 0x00000004 /* Flags for stat_ex() */ -#define LIBSSH2_SFTP_STAT 0 -#define LIBSSH2_SFTP_LSTAT 1 -#define LIBSSH2_SFTP_SETSTAT 2 +#define LIBSSH2_SFTP_STAT 0 +#define LIBSSH2_SFTP_LSTAT 1 +#define LIBSSH2_SFTP_SETSTAT 2 /* Flags for symlink_ex() */ -#define LIBSSH2_SFTP_SYMLINK 0 -#define LIBSSH2_SFTP_READLINK 1 -#define LIBSSH2_SFTP_REALPATH 2 +#define LIBSSH2_SFTP_SYMLINK 0 +#define LIBSSH2_SFTP_READLINK 1 +#define LIBSSH2_SFTP_REALPATH 2 /* SFTP attribute flag bits */ -#define LIBSSH2_SFTP_ATTR_SIZE 0x00000001 -#define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002 -#define LIBSSH2_SFTP_ATTR_PERMISSIONS 0x00000004 -#define LIBSSH2_SFTP_ATTR_ACMODTIME 0x00000008 -#define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000 +#define LIBSSH2_SFTP_ATTR_SIZE 0x00000001 +#define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002 +#define LIBSSH2_SFTP_ATTR_PERMISSIONS 0x00000004 +#define LIBSSH2_SFTP_ATTR_ACMODTIME 0x00000008 +#define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000 struct _LIBSSH2_SFTP_ATTRIBUTES { - /* If flags & ATTR_* bit is set, then the value in this struct will be meaningful - * Otherwise it should be ignored - */ - unsigned long flags; + /* If flags & ATTR_* bit is set, then the value in this struct will be meaningful + * Otherwise it should be ignored + */ + unsigned long flags; - libssh2_uint64_t filesize; - unsigned long uid, gid; - unsigned long permissions; - unsigned long atime, mtime; + libssh2_uint64_t filesize; + unsigned long uid, gid; + unsigned long permissions; + unsigned long atime, mtime; }; /* SFTP filetypes */ -#define LIBSSH2_SFTP_TYPE_REGULAR 1 -#define LIBSSH2_SFTP_TYPE_DIRECTORY 2 -#define LIBSSH2_SFTP_TYPE_SYMLINK 3 -#define LIBSSH2_SFTP_TYPE_SPECIAL 4 -#define LIBSSH2_SFTP_TYPE_UNKNOWN 5 -#define LIBSSH2_SFTP_TYPE_SOCKET 6 -#define LIBSSH2_SFTP_TYPE_CHAR_DEVICE 7 -#define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8 -#define LIBSSH2_SFTP_TYPE_FIFO 9 +#define LIBSSH2_SFTP_TYPE_REGULAR 1 +#define LIBSSH2_SFTP_TYPE_DIRECTORY 2 +#define LIBSSH2_SFTP_TYPE_SYMLINK 3 +#define LIBSSH2_SFTP_TYPE_SPECIAL 4 +#define LIBSSH2_SFTP_TYPE_UNKNOWN 5 +#define LIBSSH2_SFTP_TYPE_SOCKET 6 +#define LIBSSH2_SFTP_TYPE_CHAR_DEVICE 7 +#define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8 +#define LIBSSH2_SFTP_TYPE_FIFO 9 /* * Reproduce the POSIX file modes here for systems that are not @@ -114,64 +114,64 @@ struct _LIBSSH2_SFTP_ATTRIBUTES { * These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES" */ /* File type */ -#define LIBSSH2_SFTP_S_IFMT 0170000 /* type of file mask */ -#define LIBSSH2_SFTP_S_IFIFO 0010000 /* named pipe (fifo) */ -#define LIBSSH2_SFTP_S_IFCHR 0020000 /* character special */ -#define LIBSSH2_SFTP_S_IFDIR 0040000 /* directory */ -#define LIBSSH2_SFTP_S_IFBLK 0060000 /* block special */ -#define LIBSSH2_SFTP_S_IFREG 0100000 /* regular */ -#define LIBSSH2_SFTP_S_IFLNK 0120000 /* symbolic link */ -#define LIBSSH2_SFTP_S_IFSOCK 0140000 /* socket */ +#define LIBSSH2_SFTP_S_IFMT 0170000 /* type of file mask */ +#define LIBSSH2_SFTP_S_IFIFO 0010000 /* named pipe (fifo) */ +#define LIBSSH2_SFTP_S_IFCHR 0020000 /* character special */ +#define LIBSSH2_SFTP_S_IFDIR 0040000 /* directory */ +#define LIBSSH2_SFTP_S_IFBLK 0060000 /* block special */ +#define LIBSSH2_SFTP_S_IFREG 0100000 /* regular */ +#define LIBSSH2_SFTP_S_IFLNK 0120000 /* symbolic link */ +#define LIBSSH2_SFTP_S_IFSOCK 0140000 /* socket */ /* File mode */ /* Read, write, execute/search by owner */ -#define LIBSSH2_SFTP_S_IRWXU 0000700 /* RWX mask for owner */ -#define LIBSSH2_SFTP_S_IRUSR 0000400 /* R for owner */ -#define LIBSSH2_SFTP_S_IWUSR 0000200 /* W for owner */ -#define LIBSSH2_SFTP_S_IXUSR 0000100 /* X for owner */ +#define LIBSSH2_SFTP_S_IRWXU 0000700 /* RWX mask for owner */ +#define LIBSSH2_SFTP_S_IRUSR 0000400 /* R for owner */ +#define LIBSSH2_SFTP_S_IWUSR 0000200 /* W for owner */ +#define LIBSSH2_SFTP_S_IXUSR 0000100 /* X for owner */ /* Read, write, execute/search by group */ -#define LIBSSH2_SFTP_S_IRWXG 0000070 /* RWX mask for group */ -#define LIBSSH2_SFTP_S_IRGRP 0000040 /* R for group */ -#define LIBSSH2_SFTP_S_IWGRP 0000020 /* W for group */ -#define LIBSSH2_SFTP_S_IXGRP 0000010 /* X for group */ +#define LIBSSH2_SFTP_S_IRWXG 0000070 /* RWX mask for group */ +#define LIBSSH2_SFTP_S_IRGRP 0000040 /* R for group */ +#define LIBSSH2_SFTP_S_IWGRP 0000020 /* W for group */ +#define LIBSSH2_SFTP_S_IXGRP 0000010 /* X for group */ /* Read, write, execute/search by others */ -#define LIBSSH2_SFTP_S_IRWXO 0000007 /* RWX mask for other */ -#define LIBSSH2_SFTP_S_IROTH 0000004 /* R for other */ -#define LIBSSH2_SFTP_S_IWOTH 0000002 /* W for other */ -#define LIBSSH2_SFTP_S_IXOTH 0000001 /* X for other */ +#define LIBSSH2_SFTP_S_IRWXO 0000007 /* RWX mask for other */ +#define LIBSSH2_SFTP_S_IROTH 0000004 /* R for other */ +#define LIBSSH2_SFTP_S_IWOTH 0000002 /* W for other */ +#define LIBSSH2_SFTP_S_IXOTH 0000001 /* X for other */ /* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open()) * Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */ -#define LIBSSH2_FXF_READ 0x00000001 -#define LIBSSH2_FXF_WRITE 0x00000002 -#define LIBSSH2_FXF_APPEND 0x00000004 -#define LIBSSH2_FXF_CREAT 0x00000008 -#define LIBSSH2_FXF_TRUNC 0x00000010 -#define LIBSSH2_FXF_EXCL 0x00000020 +#define LIBSSH2_FXF_READ 0x00000001 +#define LIBSSH2_FXF_WRITE 0x00000002 +#define LIBSSH2_FXF_APPEND 0x00000004 +#define LIBSSH2_FXF_CREAT 0x00000008 +#define LIBSSH2_FXF_TRUNC 0x00000010 +#define LIBSSH2_FXF_EXCL 0x00000020 /* SFTP Status Codes (returned by libssh2_sftp_last_error() ) */ -#define LIBSSH2_FX_OK 0 -#define LIBSSH2_FX_EOF 1 -#define LIBSSH2_FX_NO_SUCH_FILE 2 -#define LIBSSH2_FX_PERMISSION_DENIED 3 -#define LIBSSH2_FX_FAILURE 4 -#define LIBSSH2_FX_BAD_MESSAGE 5 -#define LIBSSH2_FX_NO_CONNECTION 6 -#define LIBSSH2_FX_CONNECTION_LOST 7 -#define LIBSSH2_FX_OP_UNSUPPORTED 8 -#define LIBSSH2_FX_INVALID_HANDLE 9 -#define LIBSSH2_FX_NO_SUCH_PATH 10 -#define LIBSSH2_FX_FILE_ALREADY_EXISTS 11 -#define LIBSSH2_FX_WRITE_PROTECT 12 -#define LIBSSH2_FX_NO_MEDIA 13 -#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14 -#define LIBSSH2_FX_QUOTA_EXCEEDED 15 -#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16 -#define LIBSSH2_FX_LOCK_CONFlICT 17 -#define LIBSSH2_FX_DIR_NOT_EMPTY 18 -#define LIBSSH2_FX_NOT_A_DIRECTORY 19 -#define LIBSSH2_FX_INVALID_FILENAME 20 -#define LIBSSH2_FX_LINK_LOOP 21 +#define LIBSSH2_FX_OK 0 +#define LIBSSH2_FX_EOF 1 +#define LIBSSH2_FX_NO_SUCH_FILE 2 +#define LIBSSH2_FX_PERMISSION_DENIED 3 +#define LIBSSH2_FX_FAILURE 4 +#define LIBSSH2_FX_BAD_MESSAGE 5 +#define LIBSSH2_FX_NO_CONNECTION 6 +#define LIBSSH2_FX_CONNECTION_LOST 7 +#define LIBSSH2_FX_OP_UNSUPPORTED 8 +#define LIBSSH2_FX_INVALID_HANDLE 9 +#define LIBSSH2_FX_NO_SUCH_PATH 10 +#define LIBSSH2_FX_FILE_ALREADY_EXISTS 11 +#define LIBSSH2_FX_WRITE_PROTECT 12 +#define LIBSSH2_FX_NO_MEDIA 13 +#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14 +#define LIBSSH2_FX_QUOTA_EXCEEDED 15 +#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16 +#define LIBSSH2_FX_LOCK_CONFlICT 17 +#define LIBSSH2_FX_DIR_NOT_EMPTY 18 +#define LIBSSH2_FX_NOT_A_DIRECTORY 19 +#define LIBSSH2_FX_INVALID_FILENAME 20 +#define LIBSSH2_FX_LINK_LOOP 21 /* SFTP API */ LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session); @@ -180,16 +180,16 @@ LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp); /* File / Directory Ops */ LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len, unsigned long flags, long mode, int open_type); -#define libssh2_sftp_open(sftp, filename, flags, mode) libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), (mode), LIBSSH2_SFTP_OPENFILE) -#define libssh2_sftp_opendir(sftp, path) libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, LIBSSH2_SFTP_OPENDIR) +#define libssh2_sftp_open(sftp, filename, flags, mode) libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), (mode), LIBSSH2_SFTP_OPENFILE) +#define libssh2_sftp_opendir(sftp, path) libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, LIBSSH2_SFTP_OPENDIR) /* This is a public error code from libssh2_sftp_read() that is returned when it would otherwise block. */ #define LIBSSH2SFTP_EAGAIN -2 LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, - char *buffer, size_t buffer_maxlen); + char *buffer, size_t buffer_maxlen); LIBSSH2_API ssize_t libssh2_sftp_readnb(LIBSSH2_SFTP_HANDLE *handle, - char *buffer, size_t buffer_maxlen); + char *buffer, size_t buffer_maxlen); LIBSSH2_API int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs); @@ -197,52 +197,52 @@ LIBSSH2_API int libssh2_sftp_readdirnb(LIBSSH2_SFTP_HANDLE *handle, char *buffer size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs); LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, - const char *buffer, size_t count); + const char *buffer, size_t count); LIBSSH2_API ssize_t libssh2_sftp_writenb(LIBSSH2_SFTP_HANDLE *handle, - const char *buffer, size_t count); + const char *buffer, size_t count); LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle); -#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle) -#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle) +#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle) +#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle) LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset); -#define libssh2_sftp_rewind(handle) libssh2_sftp_seek((handle), 0) +#define libssh2_sftp_rewind(handle) libssh2_sftp_seek((handle), 0) LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle); LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat); -#define libssh2_sftp_fstat(handle, attrs) libssh2_sftp_fstat_ex((handle), (attrs), 0) -#define libssh2_sftp_fsetstat(handle, attrs) libssh2_sftp_fstat_ex((handle), (attrs), 1) +#define libssh2_sftp_fstat(handle, attrs) libssh2_sftp_fstat_ex((handle), (attrs), 0) +#define libssh2_sftp_fsetstat(handle, attrs) libssh2_sftp_fstat_ex((handle), (attrs), 1) /* Miscellaneous Ops */ -LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, unsigned int srouce_filename_len, - const char *dest_filename, unsigned int dest_filename_len, - long flags); -#define libssh2_sftp_rename(sftp, sourcefile, destfile) libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), (destfile), strlen(destfile), \ - LIBSSH2_SFTP_RENAME_OVERWRITE | LIBSSH2_SFTP_RENAME_ATOMIC | LIBSSH2_SFTP_RENAME_NATIVE) +LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, unsigned int srouce_filename_len, + const char *dest_filename, unsigned int dest_filename_len, + long flags); +#define libssh2_sftp_rename(sftp, sourcefile, destfile) libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), (destfile), strlen(destfile), \ + LIBSSH2_SFTP_RENAME_OVERWRITE | LIBSSH2_SFTP_RENAME_ATOMIC | LIBSSH2_SFTP_RENAME_NATIVE) LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len); -#define libssh2_sftp_unlink(sftp, filename) libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename)) +#define libssh2_sftp_unlink(sftp, filename) libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename)) LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode); -#define libssh2_sftp_mkdir(sftp, path, mode) libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode)) +#define libssh2_sftp_mkdir(sftp, path, mode) libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode)) LIBSSH2_API int libssh2_sftp_mkdirnb_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode); -#define libssh2_sftp_mkdirnb(sftp, path, mode) libssh2_sftp_mkdirnb_ex((sftp), (path), strlen(path), (mode)) +#define libssh2_sftp_mkdirnb(sftp, path, mode) libssh2_sftp_mkdirnb_ex((sftp), (path), strlen(path), (mode)) LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len); -#define libssh2_sftp_rmdir(sftp, path) libssh2_sftp_rmdir_ex((sftp), (path), strlen(path)) +#define libssh2_sftp_rmdir(sftp, path) libssh2_sftp_rmdir_ex((sftp), (path), strlen(path)) LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, int stat_type, LIBSSH2_SFTP_ATTRIBUTES *attrs); -#define libssh2_sftp_stat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, (attrs)) -#define libssh2_sftp_lstat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, (attrs)) -#define libssh2_sftp_setstat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, (attrs)) +#define libssh2_sftp_stat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, (attrs)) +#define libssh2_sftp_lstat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, (attrs)) +#define libssh2_sftp_setstat(sftp, path, attrs) libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, (attrs)) LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type); -#define libssh2_sftp_symlink(sftp, orig, linkpath) libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), strlen(linkpath), LIBSSH2_SFTP_SYMLINK) -#define libssh2_sftp_readlink(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_READLINK) -#define libssh2_sftp_realpath(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_REALPATH) +#define libssh2_sftp_symlink(sftp, orig, linkpath) libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), strlen(linkpath), LIBSSH2_SFTP_SYMLINK) +#define libssh2_sftp_readlink(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_READLINK) +#define libssh2_sftp_realpath(sftp, path, target, maxlen) libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), LIBSSH2_SFTP_REALPATH) LIBSSH2_API void libssh2_sftp_set_blocking(LIBSSH2_SFTP *session, int blocking); LIBSSH2_API int libssh2_sftp_get_blocking(LIBSSH2_SFTP *session); diff --git a/src/channel.c b/src/channel.c index 7b2660d..348bf7d 100644 --- a/src/channel.c +++ b/src/channel.c @@ -51,7 +51,7 @@ * is copied from the libcurl sources with permission. */ static int _libssh2_nonblock(int sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */) + int nonblock /* TRUE or FALSE */) { #undef SETBLOCK #define SETBLOCK 0 @@ -119,26 +119,26 @@ static int _libssh2_nonblock(int sockfd, /* operate on this */ */ unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session) { - unsigned long id = session->next_channel; - LIBSSH2_CHANNEL *channel; + unsigned long id = session->next_channel; + LIBSSH2_CHANNEL *channel; - channel = session->channels.head; + channel = session->channels.head; - while (channel) { - if (channel->local.id > id) { - id = channel->local.id; - } - channel = channel->next; - } + while (channel) { + if (channel->local.id > id) { + id = channel->local.id; + } + channel = channel->next; + } - /* This is a shortcut to avoid waiting for close packets on channels we've forgotten about, - * This *could* be a problem if we request and close 4 billion or so channels in too rapid succession - * for the remote end to respond, but the worst case scenario is that some data meant for another channel - * Gets picked up by the new one.... Pretty unlikely all told... - */ - session->next_channel = id + 1; - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocated new channel ID#%lu", id); - return id; + /* This is a shortcut to avoid waiting for close packets on channels we've forgotten about, + * This *could* be a problem if we request and close 4 billion or so channels in too rapid succession + * for the remote end to respond, but the worst case scenario is that some data meant for another channel + * Gets picked up by the new one.... Pretty unlikely all told... + */ + session->next_channel = id + 1; + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocated new channel ID#%lu", id); + return id; } /* }}} */ @@ -147,30 +147,30 @@ unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session) */ LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id) { - LIBSSH2_CHANNEL *channel = session->channels.head; - while (channel) { - if (channel->local.id == channel_id) { - return channel; - } - channel = channel->next; - } + LIBSSH2_CHANNEL *channel = session->channels.head; + while (channel) { + if (channel->local.id == channel_id) { + return channel; + } + channel = channel->next; + } - return NULL; + return NULL; } /* }}} */ -#define libssh2_channel_add(session, channel) \ -{ \ - if ((session)->channels.tail) { \ - (session)->channels.tail->next = (channel); \ - (channel)->prev = (session)->channels.tail; \ - } else { \ - (session)->channels.head = (channel); \ - (channel)->prev = NULL; \ - } \ - (channel)->next = NULL; \ - (session)->channels.tail = (channel); \ - (channel)->session = (session); \ +#define libssh2_channel_add(session, channel) \ +{ \ + if ((session)->channels.tail) { \ + (session)->channels.tail->next = (channel); \ + (channel)->prev = (session)->channels.tail; \ + } else { \ + (session)->channels.head = (channel); \ + (channel)->prev = NULL; \ + } \ + (channel)->next = NULL; \ + (session)->channels.tail = (channel); \ + (channel)->session = (session); \ } /* {{{ libssh2_channel_open_session @@ -178,157 +178,157 @@ LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long */ LIBSSH2_API LIBSSH2_CHANNEL * libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, - unsigned int channel_type_len, - unsigned int window_size, - unsigned int packet_size, const char *message, - unsigned int message_len) + unsigned int channel_type_len, + unsigned int window_size, + unsigned int packet_size, const char *message, + unsigned int message_len) { - static const unsigned char reply_codes[3] = { - SSH_MSG_CHANNEL_OPEN_CONFIRMATION, - SSH_MSG_CHANNEL_OPEN_FAILURE, - 0 - }; - LIBSSH2_CHANNEL *channel = NULL; - unsigned long local_channel = libssh2_channel_nextid(session); - unsigned char *s, *packet = NULL; - unsigned long packet_len = - channel_type_len + message_len + 17; /* packet_type(1) + - channel_type_len(4) + - sender_channel(4) + - window_size(4) + - packet_size(4) */ - unsigned char *data = NULL; - unsigned long data_len; + static const unsigned char reply_codes[3] = { + SSH_MSG_CHANNEL_OPEN_CONFIRMATION, + SSH_MSG_CHANNEL_OPEN_FAILURE, + 0 + }; + LIBSSH2_CHANNEL *channel = NULL; + unsigned long local_channel = libssh2_channel_nextid(session); + unsigned char *s, *packet = NULL; + unsigned long packet_len = + channel_type_len + message_len + 17; /* packet_type(1) + + channel_type_len(4) + + sender_channel(4) + + window_size(4) + + packet_size(4) */ + unsigned char *data = NULL; + unsigned long data_len; - _libssh2_debug(session, LIBSSH2_DBG_CONN, - "Opening Channel - win %d pack %d", - window_size, packet_size); - channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); - if (!channel) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate space for channel data", 0); - return NULL; - } - memset(channel, 0, sizeof(LIBSSH2_CHANNEL)); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Opening Channel - win %d pack %d", + window_size, packet_size); + channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if (!channel) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate space for channel data", 0); + return NULL; + } + memset(channel, 0, sizeof(LIBSSH2_CHANNEL)); - channel->channel_type_len = channel_type_len; - channel->channel_type = LIBSSH2_ALLOC(session, channel_type_len); - if (!channel->channel_type) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Failed allocating memory for channel type name", 0); - LIBSSH2_FREE(session, channel); - return NULL; - } - memcpy(channel->channel_type, channel_type, channel_type_len); + channel->channel_type_len = channel_type_len; + channel->channel_type = LIBSSH2_ALLOC(session, channel_type_len); + if (!channel->channel_type) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating memory for channel type name", 0); + LIBSSH2_FREE(session, channel); + return NULL; + } + memcpy(channel->channel_type, channel_type, channel_type_len); - /* REMEMBER: local as in locally sourced */ - channel->local.id = local_channel; - channel->remote.window_size = window_size; - channel->remote.window_size_initial = window_size; - channel->remote.packet_size = packet_size; + /* REMEMBER: local as in locally sourced */ + channel->local.id = local_channel; + channel->remote.window_size = window_size; + channel->remote.window_size_initial = window_size; + channel->remote.packet_size = packet_size; - libssh2_channel_add(session, channel); + libssh2_channel_add(session, channel); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate temporary space for packet", - 0); - goto channel_error; - } - *(s++) = SSH_MSG_CHANNEL_OPEN; - libssh2_htonu32(s, channel_type_len); - s += 4; + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate temporary space for packet", + 0); + goto channel_error; + } + *(s++) = SSH_MSG_CHANNEL_OPEN; + libssh2_htonu32(s, channel_type_len); + s += 4; - memcpy(s, channel_type, channel_type_len); - s += channel_type_len; + memcpy(s, channel_type, channel_type_len); + s += channel_type_len; - libssh2_htonu32(s, local_channel); - s += 4; + libssh2_htonu32(s, local_channel); + s += 4; - libssh2_htonu32(s, window_size); - s += 4; + libssh2_htonu32(s, window_size); + s += 4; - libssh2_htonu32(s, packet_size); - s += 4; + libssh2_htonu32(s, packet_size); + s += 4; - if (message && message_len) { - memcpy(s, message, message_len); - s += message_len; - } + if (message && message_len) { + memcpy(s, message, message_len); + s += message_len; + } - if (libssh2_packet_write(session, packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, - "Unable to send channel-open request", 0); - goto channel_error; - } + if (libssh2_packet_write(session, packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel-open request", 0); + goto channel_error; + } - if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, - 1, packet + 5 + channel_type_len, 4)) { - goto channel_error; - } + if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, + 1, packet + 5 + channel_type_len, 4)) { + goto channel_error; + } - if (data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) { - channel->remote.id = libssh2_ntohu32(data + 5); - channel->local.window_size = libssh2_ntohu32(data + 9); - channel->local.window_size_initial = libssh2_ntohu32(data + 9); - channel->local.packet_size = libssh2_ntohu32(data + 13); - _libssh2_debug(session, LIBSSH2_DBG_CONN, - "Connection Established - ID: %lu/%lu win: %lu/%lu pack: %lu/%lu", - channel->local.id, channel->remote.id, - channel->local.window_size, channel->remote.window_size, - channel->local.packet_size, channel->remote.packet_size); - LIBSSH2_FREE(session, packet); - LIBSSH2_FREE(session, data); + if (data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) { + channel->remote.id = libssh2_ntohu32(data + 5); + channel->local.window_size = libssh2_ntohu32(data + 9); + channel->local.window_size_initial = libssh2_ntohu32(data + 9); + channel->local.packet_size = libssh2_ntohu32(data + 13); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Connection Established - ID: %lu/%lu win: %lu/%lu pack: %lu/%lu", + channel->local.id, channel->remote.id, + channel->local.window_size, channel->remote.window_size, + channel->local.packet_size, channel->remote.packet_size); + LIBSSH2_FREE(session, packet); + LIBSSH2_FREE(session, data); - return channel; - } + return channel; + } - if (data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, - "Channel open failure", 0); - } + if (data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure", 0); + } channel_error: - if (data) { - LIBSSH2_FREE(session, data); - } - if (packet) { - LIBSSH2_FREE(session, packet); - } - if (channel) { - unsigned char channel_id[4]; - LIBSSH2_FREE(session, channel->channel_type); + if (data) { + LIBSSH2_FREE(session, data); + } + if (packet) { + LIBSSH2_FREE(session, packet); + } + if (channel) { + unsigned char channel_id[4]; + LIBSSH2_FREE(session, channel->channel_type); - if (channel->next) { - channel->next->prev = channel->prev; - } - if (channel->prev) { - channel->prev->next = channel->next; - } - if (session->channels.head == channel) { - session->channels.head = channel->next; - } - if (session->channels.tail == channel) { - session->channels.tail = channel->prev; - } + if (channel->next) { + channel->next->prev = channel->prev; + } + if (channel->prev) { + channel->prev->next = channel->next; + } + if (session->channels.head == channel) { + session->channels.head = channel->next; + } + if (session->channels.tail == channel) { + session->channels.tail = channel->prev; + } - /* Clear out packets meant for this channel */ - libssh2_htonu32(channel_id, channel->local.id); - while ((libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_DATA, - &data, &data_len, 1, channel_id, - 4, 0) >= 0) || - (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_DATA, - &data, &data_len, 1, channel_id, - 4, 0) >= 0)) { - LIBSSH2_FREE(session, data); - } + /* Clear out packets meant for this channel */ + libssh2_htonu32(channel_id, channel->local.id); + while ((libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_DATA, + &data, &data_len, 1, channel_id, + 4, 0) >= 0) || + (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_DATA, + &data, &data_len, 1, channel_id, + 4, 0) >= 0)) { + LIBSSH2_FREE(session, data); + } - LIBSSH2_FREE(session, channel); - } + LIBSSH2_FREE(session, channel); + } - return NULL; + return NULL; } /* }}} */ @@ -337,34 +337,34 @@ libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, */ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport) { - LIBSSH2_CHANNEL *channel; - unsigned char *message, *s; - unsigned long host_len = strlen(host), shost_len = strlen(shost); - unsigned long message_len = host_len + shost_len + 16; /* host_len(4) + port(4) + shost_len(4) + sport(4) */ + LIBSSH2_CHANNEL *channel; + unsigned char *message, *s; + unsigned long host_len = strlen(host), shost_len = strlen(shost); + unsigned long message_len = host_len + shost_len + 16; /* host_len(4) + port(4) + shost_len(4) + sport(4) */ - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting direct-tcpip session to from %s:%d to %s:%d", shost, sport, host, port); + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting direct-tcpip session to from %s:%d to %s:%d", shost, sport, host, port); - s = message = LIBSSH2_ALLOC(session, message_len); - if (!message) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for direct-tcpip connection", 0); - return NULL; - } - libssh2_htonu32(s, host_len); s += 4; - memcpy(s, host, host_len); s += host_len; - libssh2_htonu32(s, port); s += 4; + s = message = LIBSSH2_ALLOC(session, message_len); + if (!message) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for direct-tcpip connection", 0); + return NULL; + } + libssh2_htonu32(s, host_len); s += 4; + memcpy(s, host, host_len); s += host_len; + libssh2_htonu32(s, port); s += 4; - libssh2_htonu32(s, shost_len); s += 4; - memcpy(s, shost, shost_len); s += shost_len; - libssh2_htonu32(s, sport); s += 4; + libssh2_htonu32(s, shost_len); s += 4; + memcpy(s, shost, shost_len); s += shost_len; + libssh2_htonu32(s, sport); s += 4; - channel = libssh2_channel_open_ex(session, "direct-tcpip", - sizeof("direct-tcpip") - 1, - LIBSSH2_CHANNEL_WINDOW_DEFAULT, - LIBSSH2_CHANNEL_PACKET_DEFAULT, - (char *)message, message_len); - LIBSSH2_FREE(session, message); + channel = libssh2_channel_open_ex(session, "direct-tcpip", + sizeof("direct-tcpip") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, + (char *)message, message_len); + LIBSSH2_FREE(session, message); - return channel; + return channel; } /* }}} */ @@ -373,95 +373,95 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *se */ LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, int port, int *bound_port, int queue_maxsize) { - unsigned char *packet, *s, *data; - static const unsigned char reply_codes[3] = { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 }; - unsigned long data_len; - unsigned long host_len = (host ? strlen(host) : (sizeof("0.0.0.0") - 1)); - unsigned long packet_len = host_len + (sizeof("tcpip-forward") - 1) + 14; - /* packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */ + unsigned char *packet, *s, *data; + static const unsigned char reply_codes[3] = { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 }; + unsigned long data_len; + unsigned long host_len = (host ? strlen(host) : (sizeof("0.0.0.0") - 1)); + unsigned long packet_len = host_len + (sizeof("tcpip-forward") - 1) + 14; + /* packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */ - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting tcpip-forward session for %s:%d", host, port); + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting tcpip-forward session for %s:%d", host, port); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memeory for setenv packet", 0); - return NULL; - } + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memeory for setenv packet", 0); + return NULL; + } - *(s++) = SSH_MSG_GLOBAL_REQUEST; - libssh2_htonu32(s, sizeof("tcpip-forward") - 1); s += 4; - memcpy(s, "tcpip-forward", sizeof("tcpip-forward") - 1); s += sizeof("tcpip-forward") - 1; - *(s++) = 0xFF; /* want_reply */ + *(s++) = SSH_MSG_GLOBAL_REQUEST; + libssh2_htonu32(s, sizeof("tcpip-forward") - 1); s += 4; + memcpy(s, "tcpip-forward", sizeof("tcpip-forward") - 1); s += sizeof("tcpip-forward") - 1; + *(s++) = 0xFF; /* want_reply */ - libssh2_htonu32(s, host_len); s += 4; - memcpy(s, host ? host : "0.0.0.0", host_len); s += host_len; - libssh2_htonu32(s, port); s += 4; + libssh2_htonu32(s, host_len); s += 4; + memcpy(s, host ? host : "0.0.0.0", host_len); s += host_len; + libssh2_htonu32(s, port); s += 4; - if (libssh2_packet_write(session, packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send global-request packet for forward listen request", 0); - LIBSSH2_FREE(session, packet); - return NULL; - } - LIBSSH2_FREE(session, packet); + if (libssh2_packet_write(session, packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send global-request packet for forward listen request", 0); + LIBSSH2_FREE(session, packet); + return NULL; + } + LIBSSH2_FREE(session, packet); - if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { - return NULL; - } + if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { + return NULL; + } - if (data[0] == SSH_MSG_REQUEST_SUCCESS) { - LIBSSH2_LISTENER *listener; + if (data[0] == SSH_MSG_REQUEST_SUCCESS) { + LIBSSH2_LISTENER *listener; - listener = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_LISTENER)); - if (!listener) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue", 0); - LIBSSH2_FREE(session, data); - return NULL; - } - memset(listener, 0, sizeof(LIBSSH2_LISTENER)); - listener->session = session; - listener->host = LIBSSH2_ALLOC(session, host_len + 1); - if (!listener->host) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue", 0); - LIBSSH2_FREE(session, listener); - LIBSSH2_FREE(session, data); - return NULL; - } - memcpy(listener->host, host ? host : "0.0.0.0", host_len); - listener->host[host_len] = 0; - if (data_len >= 5 && !port) { - listener->port = libssh2_ntohu32(data + 1); - _libssh2_debug(session, LIBSSH2_DBG_CONN, - "Dynamic tcpip-forward port allocated: %d", - listener->port); - } else { - listener->port = port; - } + listener = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_LISTENER)); + if (!listener) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue", 0); + LIBSSH2_FREE(session, data); + return NULL; + } + memset(listener, 0, sizeof(LIBSSH2_LISTENER)); + listener->session = session; + listener->host = LIBSSH2_ALLOC(session, host_len + 1); + if (!listener->host) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue", 0); + LIBSSH2_FREE(session, listener); + LIBSSH2_FREE(session, data); + return NULL; + } + memcpy(listener->host, host ? host : "0.0.0.0", host_len); + listener->host[host_len] = 0; + if (data_len >= 5 && !port) { + listener->port = libssh2_ntohu32(data + 1); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Dynamic tcpip-forward port allocated: %d", + listener->port); + } else { + listener->port = port; + } - listener->queue_size = 0; - listener->queue_maxsize = queue_maxsize; + listener->queue_size = 0; + listener->queue_maxsize = queue_maxsize; - listener->next = session->listeners; - listener->prev = NULL; - if (session->listeners) { - session->listeners->prev = listener; - } - session->listeners = listener; + listener->next = session->listeners; + listener->prev = NULL; + if (session->listeners) { + session->listeners->prev = listener; + } + session->listeners = listener; - if (bound_port) { - *bound_port = listener->port; - } + if (bound_port) { + *bound_port = listener->port; + } - LIBSSH2_FREE(session, data); - return listener; - } + LIBSSH2_FREE(session, data); + return listener; + } - if (data[0] == SSH_MSG_REQUEST_FAILURE) { - LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED, "Unable to complete request for forward-listen", 0); - return NULL; - } + if (data[0] == SSH_MSG_REQUEST_FAILURE) { + LIBSSH2_FREE(session, data); + libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED, "Unable to complete request for forward-listen", 0); + return NULL; + } - return NULL; + return NULL; } /* }}} */ @@ -471,57 +471,57 @@ LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION */ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) { - LIBSSH2_SESSION *session = listener->session; - LIBSSH2_CHANNEL *queued = listener->queue; - unsigned char *packet, *s; - unsigned long host_len = strlen(listener->host); - unsigned long packet_len = host_len + 14 + sizeof("cancel-tcpip-forward") - 1; - /* packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */ + LIBSSH2_SESSION *session = listener->session; + LIBSSH2_CHANNEL *queued = listener->queue; + unsigned char *packet, *s; + unsigned long host_len = strlen(listener->host); + unsigned long packet_len = host_len + 14 + sizeof("cancel-tcpip-forward") - 1; + /* packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */ - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Cancelling tcpip-forward session for %s:%d", listener->host, listener->port); + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Cancelling tcpip-forward session for %s:%d", listener->host, listener->port); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memeory for setenv packet", 0); - return -1; - } + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memeory for setenv packet", 0); + return -1; + } - *(s++) = SSH_MSG_GLOBAL_REQUEST; - libssh2_htonu32(s, sizeof("cancel-tcpip-forward") - 1); s += 4; - memcpy(s, "cancel-tcpip-forward", sizeof("cancel-tcpip-forward") - 1); s += sizeof("cancel-tcpip-forward") - 1; - *(s++) = 0x00; /* want_reply */ + *(s++) = SSH_MSG_GLOBAL_REQUEST; + libssh2_htonu32(s, sizeof("cancel-tcpip-forward") - 1); s += 4; + memcpy(s, "cancel-tcpip-forward", sizeof("cancel-tcpip-forward") - 1); s += sizeof("cancel-tcpip-forward") - 1; + *(s++) = 0x00; /* want_reply */ - libssh2_htonu32(s, host_len); s += 4; - memcpy(s, listener->host, host_len); s += host_len; - libssh2_htonu32(s, listener->port); s += 4; + libssh2_htonu32(s, host_len); s += 4; + memcpy(s, listener->host, host_len); s += host_len; + libssh2_htonu32(s, listener->port); s += 4; - if (libssh2_packet_write(session, packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send global-request packet for forward listen request", 0); - LIBSSH2_FREE(session, packet); - return -1; - } - LIBSSH2_FREE(session, packet); + if (libssh2_packet_write(session, packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send global-request packet for forward listen request", 0); + LIBSSH2_FREE(session, packet); + return -1; + } + LIBSSH2_FREE(session, packet); - while (queued) { - LIBSSH2_CHANNEL *next = queued->next; + while (queued) { + LIBSSH2_CHANNEL *next = queued->next; - libssh2_channel_free(queued); - queued = next; - } - LIBSSH2_FREE(session, listener->host); + libssh2_channel_free(queued); + queued = next; + } + LIBSSH2_FREE(session, listener->host); - if (listener->next) { - listener->next->prev = listener->prev; - } - if (listener->prev) { - listener->prev->next = listener->next; - } else { - session->listeners = listener->next; - } + if (listener->next) { + listener->next->prev = listener->prev; + } + if (listener->prev) { + listener->prev->next = listener->next; + } else { + session->listeners = listener->next; + } - LIBSSH2_FREE(session, listener); + LIBSSH2_FREE(session, listener); - return 0; + return 0; } /* }}} */ @@ -531,42 +531,42 @@ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) LIBSSH2_API LIBSSH2_CHANNEL * libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener) { - libssh2pack_t rc; - int loop=-1; - do { - rc = libssh2_packet_read(listener->session); - loop++; - } while (rc > 0); + libssh2pack_t rc; + int loop=-1; + do { + rc = libssh2_packet_read(listener->session); + loop++; + } while (rc > 0); - /* dast: now this might have returned with EAGAIN status which might - be somehow signalled to the caller... */ + /* dast: now this might have returned with EAGAIN status which might + be somehow signalled to the caller... */ - if (listener->queue) { - LIBSSH2_SESSION *session = listener->session; - LIBSSH2_CHANNEL *channel; + if (listener->queue) { + LIBSSH2_SESSION *session = listener->session; + LIBSSH2_CHANNEL *channel; - channel = listener->queue; + channel = listener->queue; - listener->queue = listener->queue->next; - if (listener->queue) { - listener->queue->prev = NULL; - } + listener->queue = listener->queue->next; + if (listener->queue) { + listener->queue->prev = NULL; + } - channel->prev = NULL; - channel->next = session->channels.head; - session->channels.head = channel; + channel->prev = NULL; + channel->next = session->channels.head; + session->channels.head = channel; - if (channel->next) { - channel->next->prev = channel; - } else { - session->channels.tail = channel; - } - listener->queue_size--; + if (channel->next) { + channel->next->prev = channel; + } else { + session->channels.tail = channel; + } + listener->queue_size--; - return channel; - } + return channel; + } - return NULL; + return NULL; } /* }}} */ @@ -575,55 +575,55 @@ libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener) */ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int varname_len, const char *value, unsigned int value_len) { - LIBSSH2_SESSION *session = channel->session; - unsigned char *s, *packet, *data, local_channel[4]; - static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; - unsigned long data_len; - unsigned long packet_len = varname_len + value_len + 21; /* packet_type(1) + channel_id(4) + request_len(4) + request(3)"env" + - want_reply(1) + varname_len(4) + value_len(4) */ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s, *packet, *data, local_channel[4]; + static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + unsigned long data_len; + unsigned long packet_len = varname_len + value_len + 21; /* packet_type(1) + channel_id(4) + request_len(4) + request(3)"env" + + want_reply(1) + varname_len(4) + value_len(4) */ - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Setting remote environment variable: %s=%s on channel %lu/%lu", varname, value, channel->local.id, channel->remote.id); + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Setting remote environment variable: %s=%s on channel %lu/%lu", varname, value, channel->local.id, channel->remote.id); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memeory for setenv packet", 0); - return -1; - } + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memeory for setenv packet", 0); + return -1; + } - *(s++) = SSH_MSG_CHANNEL_REQUEST; - libssh2_htonu32(s, channel->remote.id); s += 4; - libssh2_htonu32(s, sizeof("env") - 1); s += 4; - memcpy(s, "env", sizeof("env") - 1); s += sizeof("env") - 1; + *(s++) = SSH_MSG_CHANNEL_REQUEST; + libssh2_htonu32(s, channel->remote.id); s += 4; + libssh2_htonu32(s, sizeof("env") - 1); s += 4; + memcpy(s, "env", sizeof("env") - 1); s += sizeof("env") - 1; - *(s++) = 0xFF; + *(s++) = 0xFF; - libssh2_htonu32(s, varname_len); s += 4; - memcpy(s, varname, varname_len); s += varname_len; + libssh2_htonu32(s, varname_len); s += 4; + memcpy(s, varname, varname_len); s += varname_len; - libssh2_htonu32(s, value_len); s += 4; - memcpy(s, value, value_len); s += value_len; + libssh2_htonu32(s, value_len); s += 4; + memcpy(s, value, value_len); s += value_len; - if (libssh2_packet_write(session, packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel-request packet for setenv request", 0); - LIBSSH2_FREE(session, packet); - return -1; - } - LIBSSH2_FREE(session, packet); + if (libssh2_packet_write(session, packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel-request packet for setenv request", 0); + LIBSSH2_FREE(session, packet); + return -1; + } + LIBSSH2_FREE(session, packet); - libssh2_htonu32(local_channel, channel->local.id); - if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) { - return -1; - } + libssh2_htonu32(local_channel, channel->local.id); + if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) { + return -1; + } - if (data[0] == SSH_MSG_CHANNEL_SUCCESS) { - LIBSSH2_FREE(session, data); - return 0; - } + if (data[0] == SSH_MSG_CHANNEL_SUCCESS) { + LIBSSH2_FREE(session, data); + return 0; + } - LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, - "Unable to complete request for channel-setenv", 0); - return -1; + LIBSSH2_FREE(session, data); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel-setenv", 0); + return -1; } /* }}} */ @@ -631,146 +631,146 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varnam * Duh... Request a PTY */ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsigned int term_len, - const char *modes, unsigned int modes_len, - int width, int height, - int width_px, int height_px) + const char *modes, unsigned int modes_len, + int width, int height, + int width_px, int height_px) { - LIBSSH2_SESSION *session = channel->session; - unsigned char *s, *packet, *data, local_channel[4]; - static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; - unsigned long data_len; - unsigned long packet_len = term_len + modes_len + 41; /* packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) + want_reply(1) + - term_len(4) + width(4) + height(4) + width_px(4) + height_px(4) + modes_len(4) */ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s, *packet, *data, local_channel[4]; + static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + unsigned long data_len; + unsigned long packet_len = term_len + modes_len + 41; /* packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) + want_reply(1) + + term_len(4) + width(4) + height(4) + width_px(4) + height_px(4) + modes_len(4) */ - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocating tty on channel %lu/%lu", channel->local.id, channel->remote.id); + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocating tty on channel %lu/%lu", channel->local.id, channel->remote.id); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for pty-request", 0); - return -1; - } + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for pty-request", 0); + return -1; + } - *(s++) = SSH_MSG_CHANNEL_REQUEST; - libssh2_htonu32(s, channel->remote.id); s += 4; - libssh2_htonu32(s, sizeof("pty-req") - 1); s += 4; - memcpy(s, "pty-req", sizeof("pty-req") - 1); s += sizeof("pty-req") - 1; + *(s++) = SSH_MSG_CHANNEL_REQUEST; + libssh2_htonu32(s, channel->remote.id); s += 4; + libssh2_htonu32(s, sizeof("pty-req") - 1); s += 4; + memcpy(s, "pty-req", sizeof("pty-req") - 1); s += sizeof("pty-req") - 1; - *(s++) = 0xFF; + *(s++) = 0xFF; - libssh2_htonu32(s, term_len); s += 4; - if (term) { - memcpy(s, term, term_len); s += term_len; - } + libssh2_htonu32(s, term_len); s += 4; + if (term) { + memcpy(s, term, term_len); s += term_len; + } - libssh2_htonu32(s, width); s += 4; - libssh2_htonu32(s, height); s += 4; - libssh2_htonu32(s, width_px); s += 4; - libssh2_htonu32(s, height_px); s += 4; + libssh2_htonu32(s, width); s += 4; + libssh2_htonu32(s, height); s += 4; + libssh2_htonu32(s, width_px); s += 4; + libssh2_htonu32(s, height_px); s += 4; - libssh2_htonu32(s, modes_len); s += 4; - if (modes) { - memcpy(s, modes, modes_len); s += modes_len; - } + libssh2_htonu32(s, modes_len); s += 4; + if (modes) { + memcpy(s, modes, modes_len); s += modes_len; + } - if (libssh2_packet_write(session, packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send pty-request packet", 0); - LIBSSH2_FREE(session, packet); - return -1; - } - LIBSSH2_FREE(session, packet); + if (libssh2_packet_write(session, packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send pty-request packet", 0); + LIBSSH2_FREE(session, packet); + return -1; + } + LIBSSH2_FREE(session, packet); - libssh2_htonu32(local_channel, channel->local.id); - if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) { - return -1; - } + libssh2_htonu32(local_channel, channel->local.id); + if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) { + return -1; + } - if (data[0] == SSH_MSG_CHANNEL_SUCCESS) { - LIBSSH2_FREE(session, data); - return 0; - } + if (data[0] == SSH_MSG_CHANNEL_SUCCESS) { + LIBSSH2_FREE(session, data); + return 0; + } - LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel request-pty", 0); - return -1; + LIBSSH2_FREE(session, data); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel request-pty", 0); + return -1; } /* }}} */ /* Keep this an even number */ -#define LIBSSH2_X11_RANDOM_COOKIE_LEN 32 +#define LIBSSH2_X11_RANDOM_COOKIE_LEN 32 /* {{{ libssh2_channel_x11_req_ex * Request X11 forwarding */ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, const char *auth_proto, const char *auth_cookie, int screen_number) { - LIBSSH2_SESSION *session = channel->session; - unsigned char *s, *packet, *data, local_channel[4]; - static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; - unsigned long data_len; - unsigned long proto_len = auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1); - unsigned long cookie_len = auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN; - unsigned long packet_len = proto_len + cookie_len + 30; /* packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) + want_reply(1) + - single_cnx(1) + proto_len(4) + cookie_len(4) + screen_num(4) */ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s, *packet, *data, local_channel[4]; + static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + unsigned long data_len; + unsigned long proto_len = auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1); + unsigned long cookie_len = auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN; + unsigned long packet_len = proto_len + cookie_len + 30; /* packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) + want_reply(1) + + single_cnx(1) + proto_len(4) + cookie_len(4) + screen_num(4) */ - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting x11-req for channel %lu/%lu: single=%d proto=%s cookie=%s screen=%d", - channel->local.id, channel->remote.id, single_connection, - auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", - auth_cookie ? auth_cookie : "", screen_number); + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting x11-req for channel %lu/%lu: single=%d proto=%s cookie=%s screen=%d", + channel->local.id, channel->remote.id, single_connection, + auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", + auth_cookie ? auth_cookie : "", screen_number); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for pty-request", 0); - return -1; - } + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for pty-request", 0); + return -1; + } - *(s++) = SSH_MSG_CHANNEL_REQUEST; - libssh2_htonu32(s, channel->remote.id); s += 4; - libssh2_htonu32(s, sizeof("x11-req") - 1); s += 4; - memcpy(s, "x11-req", sizeof("x11-req") - 1); s += sizeof("x11-req") - 1; + *(s++) = SSH_MSG_CHANNEL_REQUEST; + libssh2_htonu32(s, channel->remote.id); s += 4; + libssh2_htonu32(s, sizeof("x11-req") - 1); s += 4; + memcpy(s, "x11-req", sizeof("x11-req") - 1); s += sizeof("x11-req") - 1; - *(s++) = 0xFF; /* want_reply */ - *(s++) = single_connection ? 0xFF : 0x00; + *(s++) = 0xFF; /* want_reply */ + *(s++) = single_connection ? 0xFF : 0x00; - libssh2_htonu32(s, proto_len); s += 4; - memcpy(s, auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", proto_len); - s += proto_len; + libssh2_htonu32(s, proto_len); s += 4; + memcpy(s, auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", proto_len); + s += proto_len; - libssh2_htonu32(s, cookie_len); s += 4; - if (auth_cookie) { - memcpy(s, auth_cookie, cookie_len); - } else { - int i; - unsigned char buffer[LIBSSH2_X11_RANDOM_COOKIE_LEN / 2]; + libssh2_htonu32(s, cookie_len); s += 4; + if (auth_cookie) { + memcpy(s, auth_cookie, cookie_len); + } else { + int i; + unsigned char buffer[LIBSSH2_X11_RANDOM_COOKIE_LEN / 2]; - libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); - for (i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) { - snprintf((char *)s + (i * 2), 2, "%02X", buffer[i]); - } - } - s += cookie_len; + libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); + for (i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) { + snprintf((char *)s + (i * 2), 2, "%02X", buffer[i]); + } + } + s += cookie_len; - libssh2_htonu32(s, screen_number); s += 4; + libssh2_htonu32(s, screen_number); s += 4; - if (libssh2_packet_write(session, packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send x11-req packet", 0); - LIBSSH2_FREE(session, packet); - return -1; - } - LIBSSH2_FREE(session, packet); + if (libssh2_packet_write(session, packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send x11-req packet", 0); + LIBSSH2_FREE(session, packet); + return -1; + } + LIBSSH2_FREE(session, packet); - libssh2_htonu32(local_channel, channel->local.id); + libssh2_htonu32(local_channel, channel->local.id); - if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) { - return -1; - } + if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) { + return -1; + } - if (data[0] == SSH_MSG_CHANNEL_SUCCESS) { - LIBSSH2_FREE(session, data); - return 0; - } + if (data[0] == SSH_MSG_CHANNEL_SUCCESS) { + LIBSSH2_FREE(session, data); + return 0; + } - LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel x11-req", 0); - return -1; + LIBSSH2_FREE(session, data); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel x11-req", 0); + return -1; } /* }}} */ @@ -779,57 +779,57 @@ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_ */ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, unsigned int request_len, const char *message, unsigned int message_len) { - LIBSSH2_SESSION *session = channel->session; - unsigned char *s, *packet, *data, local_channel[4]; - static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; - unsigned long data_len; - unsigned long packet_len = request_len + 10; /* packet_type(1) + channel(4) + request_len(4) + want_reply(1) */ - libssh2pack_t rc; + LIBSSH2_SESSION *session = channel->session; + unsigned char *s, *packet, *data, local_channel[4]; + static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + unsigned long data_len; + unsigned long packet_len = request_len + 10; /* packet_type(1) + channel(4) + request_len(4) + want_reply(1) */ + libssh2pack_t rc; - if (message) { - packet_len += message_len + 4; - } + if (message) { + packet_len += message_len + 4; + } - _libssh2_debug(session, LIBSSH2_DBG_CONN, "starting request(%s) on channel %lu/%lu, message=%s", request, channel->local.id, channel->remote.id, message); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for channel-process request", 0); - return -1; - } + _libssh2_debug(session, LIBSSH2_DBG_CONN, "starting request(%s) on channel %lu/%lu, message=%s", request, channel->local.id, channel->remote.id, message); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for channel-process request", 0); + return -1; + } - *(s++) = SSH_MSG_CHANNEL_REQUEST; - libssh2_htonu32(s, channel->remote.id); s += 4; - libssh2_htonu32(s, request_len); s += 4; - memcpy(s, request, request_len); s += request_len; + *(s++) = SSH_MSG_CHANNEL_REQUEST; + libssh2_htonu32(s, channel->remote.id); s += 4; + libssh2_htonu32(s, request_len); s += 4; + memcpy(s, request, request_len); s += request_len; - *(s++) = 0xFF; + *(s++) = 0xFF; - if (message) { - libssh2_htonu32(s, message_len); s += 4; - memcpy(s, message, message_len); s += message_len; - } + if (message) { + libssh2_htonu32(s, message_len); s += 4; + memcpy(s, message, message_len); s += message_len; + } - rc = libssh2_packet_write(session, packet, packet_len); - if(rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel request", 0); - LIBSSH2_FREE(session, packet); - return -1; - } - LIBSSH2_FREE(session, packet); + rc = libssh2_packet_write(session, packet, packet_len); + if(rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel request", 0); + LIBSSH2_FREE(session, packet); + return -1; + } + LIBSSH2_FREE(session, packet); - libssh2_htonu32(local_channel, channel->local.id); - if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) { - return -1; - } + libssh2_htonu32(local_channel, channel->local.id); + if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) { + return -1; + } - if (data[0] == SSH_MSG_CHANNEL_SUCCESS) { - LIBSSH2_FREE(session, data); - return 0; - } + if (data[0] == SSH_MSG_CHANNEL_SUCCESS) { + LIBSSH2_FREE(session, data); + return 0; + } - LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel-process-startup", 0); - return -1; + LIBSSH2_FREE(session, data); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel-process-startup", 0); + return -1; } /* }}} */ @@ -838,21 +838,21 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const * function is called. */ int _libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, - int blocking) + int blocking) { - int bl = channel->blocking; - _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, - "Setting blocking mode on channel %lu/%lu to %d", - channel->local.id, channel->remote.id, blocking); - if(blocking == channel->blocking) { - /* avoid if already correct */ - return bl; - } - channel->blocking = blocking; + int bl = channel->blocking; + _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, + "Setting blocking mode on channel %lu/%lu to %d", + channel->local.id, channel->remote.id, blocking); + if(blocking == channel->blocking) { + /* avoid if already correct */ + return bl; + } + channel->blocking = blocking; - _libssh2_nonblock(channel->session->socket_fd, !blocking); + _libssh2_nonblock(channel->session->socket_fd, !blocking); - return bl; + return bl; } /* }}} */ @@ -861,9 +861,9 @@ int _libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, * fcntl(fd, F_SETFL, O_NONBLOCK); type command */ LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, - int blocking) + int blocking) { - (void)_libssh2_channel_set_blocking(channel, blocking); + (void)_libssh2_channel_set_blocking(channel, blocking); } /* }}} */ @@ -872,7 +872,7 @@ LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, */ int libssh2_channel_get_blocking(LIBSSH2_CHANNEL *channel) { - return channel->blocking; + return channel->blocking; } /* }}} */ @@ -882,63 +882,63 @@ int libssh2_channel_get_blocking(LIBSSH2_CHANNEL *channel) */ LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid) { - LIBSSH2_PACKET *packet = channel->session->packets.head; - unsigned long refund_bytes = 0, flush_bytes = 0; + LIBSSH2_PACKET *packet = channel->session->packets.head; + unsigned long refund_bytes = 0, flush_bytes = 0; - while (packet) { - LIBSSH2_PACKET *next = packet->next; - unsigned char packet_type = packet->data[0]; + while (packet) { + LIBSSH2_PACKET *next = packet->next; + unsigned char packet_type = packet->data[0]; - if (((packet_type == SSH_MSG_CHANNEL_DATA) || - (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) && - (libssh2_ntohu32(packet->data + 1) == channel->local.id)) { - /* It's our channel at least */ - long packet_stream_id = - (packet_type == SSH_MSG_CHANNEL_DATA) ? - 0 : libssh2_ntohu32(packet->data + 5); - if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL) || - ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) && - ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) || - (streamid == packet_stream_id))) || - ((packet_type == SSH_MSG_CHANNEL_DATA) && - (streamid == 0))) { - int bytes_to_flush = - packet->data_len - packet->data_head; - _libssh2_debug(channel->session, - LIBSSH2_DBG_CONN, - "Flushing %d bytes of data from " - "stream %lu on channel %lu/%lu", - bytes_to_flush, - packet_stream_id, - channel->local.id, - channel->remote.id); + if (((packet_type == SSH_MSG_CHANNEL_DATA) || + (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) && + (libssh2_ntohu32(packet->data + 1) == channel->local.id)) { + /* It's our channel at least */ + long packet_stream_id = + (packet_type == SSH_MSG_CHANNEL_DATA) ? + 0 : libssh2_ntohu32(packet->data + 5); + if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL) || + ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) && + ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) || + (streamid == packet_stream_id))) || + ((packet_type == SSH_MSG_CHANNEL_DATA) && + (streamid == 0))) { + int bytes_to_flush = + packet->data_len - packet->data_head; + _libssh2_debug(channel->session, + LIBSSH2_DBG_CONN, + "Flushing %d bytes of data from " + "stream %lu on channel %lu/%lu", + bytes_to_flush, + packet_stream_id, + channel->local.id, + channel->remote.id); - /* It's one of the streams we wanted to flush */ - refund_bytes += packet->data_len - 13; - flush_bytes += bytes_to_flush; + /* It's one of the streams we wanted to flush */ + refund_bytes += packet->data_len - 13; + flush_bytes += bytes_to_flush; - LIBSSH2_FREE(channel->session, packet->data); - if (packet->prev) { - packet->prev->next = packet->next; - } else { - channel->session->packets.head = packet->next; - } - if (packet->next) { - packet->next->prev = packet->prev; - } else { - channel->session->packets.tail = packet->prev; - } - LIBSSH2_FREE(channel->session, packet); - } - } - packet = next; - } + LIBSSH2_FREE(channel->session, packet->data); + if (packet->prev) { + packet->prev->next = packet->next; + } else { + channel->session->packets.head = packet->next; + } + if (packet->next) { + packet->next->prev = packet->prev; + } else { + channel->session->packets.tail = packet->prev; + } + LIBSSH2_FREE(channel->session, packet); + } + } + packet = next; + } - if (refund_bytes) { - libssh2_channel_receive_window_adjust(channel, refund_bytes, 0); - } + if (refund_bytes) { + libssh2_channel_receive_window_adjust(channel, refund_bytes, 0); + } - return flush_bytes; + return flush_bytes; } /* }}} */ @@ -947,7 +947,7 @@ LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid) */ LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel) { - return channel->exit_status; + return channel->exit_status; } /* }}} */ @@ -961,36 +961,36 @@ LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel) */ LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force) { - unsigned char adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */ + unsigned char adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */ - if (!force && (adjustment + channel->adjust_queue < LIBSSH2_CHANNEL_MINADJUST)) { - _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Queueing %lu bytes for receive window adjustment for channel %lu/%lu", adjustment, channel->local.id, channel->remote.id); - channel->adjust_queue += adjustment; - return channel->remote.window_size; - } + if (!force && (adjustment + channel->adjust_queue < LIBSSH2_CHANNEL_MINADJUST)) { + _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Queueing %lu bytes for receive window adjustment for channel %lu/%lu", adjustment, channel->local.id, channel->remote.id); + channel->adjust_queue += adjustment; + return channel->remote.window_size; + } - if (!adjustment && !channel->adjust_queue) { - return channel->remote.window_size; - } + if (!adjustment && !channel->adjust_queue) { + return channel->remote.window_size; + } - adjustment += channel->adjust_queue; - channel->adjust_queue = 0; + adjustment += channel->adjust_queue; + channel->adjust_queue = 0; - /* Adjust the window based on the block we just freed */ - adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST; - libssh2_htonu32(adjust + 1, channel->remote.id); - libssh2_htonu32(adjust + 5, adjustment); - _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Adjusting window %lu bytes for data flushed from channel %lu/%lu", adjustment, channel->local.id, channel->remote.id); + /* Adjust the window based on the block we just freed */ + adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST; + libssh2_htonu32(adjust + 1, channel->remote.id); + libssh2_htonu32(adjust + 5, adjustment); + _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Adjusting window %lu bytes for data flushed from channel %lu/%lu", adjustment, channel->local.id, channel->remote.id); - if (libssh2_packet_write(channel->session, adjust, 9)) { - libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet, deferring", 0); - channel->adjust_queue = adjustment; - } else { - channel->remote.window_size += adjustment; - } + if (libssh2_packet_write(channel->session, adjust, 9)) { + libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet, deferring", 0); + channel->adjust_queue = adjustment; + } else { + channel->remote.window_size += adjustment; + } - return channel->remote.window_size; + return channel->remote.window_size; } /* }}} */ @@ -1002,12 +1002,12 @@ LIBSSH2_API unsigned long libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL */ LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode) { - _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Setting channel %lu/%lu handle_extended_data mode to %d", channel->local.id, channel->remote.id, ignore_mode); - channel->remote.extended_data_ignore_mode = ignore_mode; + _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Setting channel %lu/%lu handle_extended_data mode to %d", channel->local.id, channel->remote.id, ignore_mode); + channel->remote.extended_data_ignore_mode = ignore_mode; - if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) { - libssh2_channel_flush_ex(channel, LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA); - } + if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) { + libssh2_channel_flush_ex(channel, LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA); + } } /* }}} */ @@ -1020,182 +1020,182 @@ LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, * PACKET_EAGAIN. */ ssize_t _libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, - int stream_id, char *buf, size_t buflen) + int stream_id, char *buf, size_t buflen) { - LIBSSH2_SESSION *session = channel->session; - int bytes_read = 0; - LIBSSH2_PACKET *packet; - libssh2pack_t rc=0; - int bl; - int block=0; + LIBSSH2_SESSION *session = channel->session; + int bytes_read = 0; + LIBSSH2_PACKET *packet; + libssh2pack_t rc=0; + int bl; + int block=0; - _libssh2_debug(session, LIBSSH2_DBG_CONN, - "Attempting to read %d bytes from channel %lu/%lu stream #%d", - (int)buflen, - channel->local.id, channel->remote.id, stream_id); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Attempting to read %d bytes from channel %lu/%lu stream #%d", + (int)buflen, + channel->local.id, channel->remote.id, stream_id); - /* set non-blocking and remember previous state */ - bl = _libssh2_channel_set_blocking(channel, 0); + /* set non-blocking and remember previous state */ + bl = _libssh2_channel_set_blocking(channel, 0); - /* process all incoming packets */ - do { - rc = libssh2_packet_read(session); - } while (rc > 0); + /* process all incoming packets */ + do { + rc = libssh2_packet_read(session); + } while (rc > 0); - if((rc < 0) && (rc != PACKET_EAGAIN)) { - return rc; - } - rc = 0; + if((rc < 0) && (rc != PACKET_EAGAIN)) { + return rc; + } + rc = 0; - /* restore blocking state */ - _libssh2_channel_set_blocking(channel, bl); + /* restore blocking state */ + _libssh2_channel_set_blocking(channel, bl); - packet = session->packets.head; + packet = session->packets.head; - do { + do { - if(block) { - /* in the second lap and onwards, do this */ - rc = libssh2_packet_read(session); - packet = session->packets.head; - } + if(block) { + /* in the second lap and onwards, do this */ + rc = libssh2_packet_read(session); + packet = session->packets.head; + } - if(rc < 0) { - /* no packets available */ - return rc; - } + if(rc < 0) { + /* no packets available */ + return rc; + } - while (packet && (bytes_read < (int)buflen)) { - /* In case packet gets destroyed during this - iteration */ - LIBSSH2_PACKET *next = packet->next; + while (packet && (bytes_read < (int)buflen)) { + /* In case packet gets destroyed during this + iteration */ + LIBSSH2_PACKET *next = packet->next; - uint32_t local_id = libssh2_ntohu32(packet->data + 1); + uint32_t local_id = libssh2_ntohu32(packet->data + 1); - /* Either we asked for a specific extended data stream - * (and data was available), - * or the standard stream (and data was available), - * or the standard stream with extended_data_merge - * enabled and data was available - */ - if ((stream_id && - (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && - (channel->local.id == local_id) && - (stream_id == (int)libssh2_ntohu32(packet->data + 5))) || + /* Either we asked for a specific extended data stream + * (and data was available), + * or the standard stream (and data was available), + * or the standard stream with extended_data_merge + * enabled and data was available + */ + if ((stream_id && + (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && + (channel->local.id == local_id) && + (stream_id == (int)libssh2_ntohu32(packet->data + 5))) || - (!stream_id && - (packet->data[0] == SSH_MSG_CHANNEL_DATA) && - (channel->local.id == local_id)) || + (!stream_id && + (packet->data[0] == SSH_MSG_CHANNEL_DATA) && + (channel->local.id == local_id)) || - (!stream_id && - (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && - (channel->local.id == local_id) && - (channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { + (!stream_id && + (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && + (channel->local.id == local_id) && + (channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { - int want = buflen - bytes_read; - int unlink_packet = 0; + int want = buflen - bytes_read; + int unlink_packet = 0; - if (want >= (int)(packet->data_len - packet->data_head)) { - want = packet->data_len - packet->data_head; - unlink_packet = 1; - } + if (want >= (int)(packet->data_len - packet->data_head)) { + want = packet->data_len - packet->data_head; + unlink_packet = 1; + } - _libssh2_debug(session, LIBSSH2_DBG_CONN, - "Reading %d of buffered data from %lu/%lu/%d", - want, channel->local.id, - channel->remote.id, stream_id); - memcpy(buf + bytes_read, packet->data + packet->data_head, want); - packet->data_head += want; - bytes_read += want; + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Reading %d of buffered data from %lu/%lu/%d", + want, channel->local.id, + channel->remote.id, stream_id); + memcpy(buf + bytes_read, packet->data + packet->data_head, want); + packet->data_head += want; + bytes_read += want; - if (unlink_packet) { - if (packet->prev) { - packet->prev->next = packet->next; - } else { - session->packets.head = packet->next; - } - if (packet->next) { - packet->next->prev = packet->prev; - } else { - session->packets.tail = packet->prev; - } - LIBSSH2_FREE(session, packet->data); + if (unlink_packet) { + if (packet->prev) { + packet->prev->next = packet->next; + } else { + session->packets.head = packet->next; + } + if (packet->next) { + packet->next->prev = packet->prev; + } else { + session->packets.tail = packet->prev; + } + LIBSSH2_FREE(session, packet->data); - _libssh2_debug(session, - LIBSSH2_DBG_CONN, - "Unlinking empty packet buffer from channel %lu/%lu", - channel->local.id, channel->remote.id); + _libssh2_debug(session, + LIBSSH2_DBG_CONN, + "Unlinking empty packet buffer from channel %lu/%lu", + channel->local.id, channel->remote.id); - libssh2_channel_receive_window_adjust(channel, packet->data_len - (stream_id ? 13 : 9), 0); - LIBSSH2_FREE(session, packet); - } - } - packet = next; - } - block=1; + libssh2_channel_receive_window_adjust(channel, packet->data_len - (stream_id ? 13 : 9), 0); + LIBSSH2_FREE(session, packet); + } + } + packet = next; + } + block=1; - } while (channel->blocking && (bytes_read == 0) && - !channel->remote.close); + } while (channel->blocking && (bytes_read == 0) && + !channel->remote.close); - if (bytes_read == 0) { - if(channel->blocking) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, - "Remote end has closed this channel", 0); - } - else { - /* when non-blocking, we must return PACKET_EAGAIN if - we haven't completed reading the channel */ - if(!libssh2_channel_eof(channel)) { - return PACKET_EAGAIN; - } - } - } + if (bytes_read == 0) { + if(channel->blocking) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, + "Remote end has closed this channel", 0); + } + else { + /* when non-blocking, we must return PACKET_EAGAIN if + we haven't completed reading the channel */ + if(!libssh2_channel_eof(channel)) { + return PACKET_EAGAIN; + } + } + } - return bytes_read; + return bytes_read; } /* }}} */ LIBSSH2_API int libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, - int stream_id, - char *buf, size_t buflen) + int stream_id, + char *buf, size_t buflen) { - ssize_t rc; - int bl; + ssize_t rc; + int bl; - /* set blocking */ - bl = _libssh2_channel_set_blocking(channel, 1); + /* set blocking */ + bl = _libssh2_channel_set_blocking(channel, 1); - rc = _libssh2_channel_read_ex(channel, stream_id, buf, buflen); + rc = _libssh2_channel_read_ex(channel, stream_id, buf, buflen); - /* restore state */ - _libssh2_channel_set_blocking(channel, bl); + /* restore state */ + _libssh2_channel_set_blocking(channel, bl); - if(rc < 0) { - /* precent accidental returning of other return codes since - this API does not support/provide those */ - return -1; - } + if(rc < 0) { + /* precent accidental returning of other return codes since + this API does not support/provide those */ + return -1; + } - return rc; + return rc; } LIBSSH2_API int libssh2_channel_readnb_ex(LIBSSH2_CHANNEL *channel, - int stream_id, - char *buf, size_t buflen) + int stream_id, + char *buf, size_t buflen) { - ssize_t rc; + ssize_t rc; - /* set non-blocking */ - int bl = _libssh2_channel_set_blocking(channel, 0); + /* set non-blocking */ + int bl = _libssh2_channel_set_blocking(channel, 0); - rc = _libssh2_channel_read_ex(channel, stream_id, buf, buflen); + rc = _libssh2_channel_read_ex(channel, stream_id, buf, buflen); - /* restore state */ - _libssh2_channel_set_blocking(channel, bl); + /* restore state */ + _libssh2_channel_set_blocking(channel, bl); - return rc; + return rc; } @@ -1203,98 +1203,98 @@ LIBSSH2_API int libssh2_channel_readnb_ex(LIBSSH2_CHANNEL *channel, * Send data to a channel */ int _libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, - int stream_id, - const char *buf, size_t buflen) + int stream_id, + const char *buf, size_t buflen) { - LIBSSH2_SESSION *session = channel->session; - unsigned char *packet; - unsigned long packet_len, bufwrote = 0; + LIBSSH2_SESSION *session = channel->session; + unsigned char *packet; + unsigned long packet_len, bufwrote = 0; - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Writing %d bytes on channel %lu/%lu, stream #%d", (int)buflen, channel->local.id, channel->remote.id, stream_id); - if (channel->local.close) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "We've already closed this channel", 0); - return -1; - } + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Writing %d bytes on channel %lu/%lu, stream #%d", (int)buflen, channel->local.id, channel->remote.id, stream_id); + if (channel->local.close) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "We've already closed this channel", 0); + return -1; + } - if (channel->local.eof) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_EOF_SENT, "EOF has already been sight, data might be ignored", 0); - } + if (channel->local.eof) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_EOF_SENT, "EOF has already been sight, data might be ignored", 0); + } - if (!channel->blocking && (channel->local.window_size <= 0)) { - /* Can't write anything */ - return 0; - } + if (!channel->blocking && (channel->local.window_size <= 0)) { + /* Can't write anything */ + return 0; + } - packet_len = buflen + (stream_id ? 13 : 9); /* packet_type(1) + channelno(4) [ + streamid(4) ] + buflen(4) */ - packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocte space for data transmission packet", 0); - return -1; - } + packet_len = buflen + (stream_id ? 13 : 9); /* packet_type(1) + channelno(4) [ + streamid(4) ] + buflen(4) */ + packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocte space for data transmission packet", 0); + return -1; + } - while (buflen > 0) { - size_t bufwrite = buflen; - unsigned char *s = packet; - libssh2pack_t rc; + while (buflen > 0) { + size_t bufwrite = buflen; + unsigned char *s = packet; + libssh2pack_t rc; - *(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA; - libssh2_htonu32(s, channel->remote.id); s += 4; - if (stream_id) { - libssh2_htonu32(s, stream_id); s += 4; - } + *(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA; + libssh2_htonu32(s, channel->remote.id); s += 4; + if (stream_id) { + libssh2_htonu32(s, stream_id); s += 4; + } - /* twiddle our thumbs until there's window space available */ - while (channel->local.window_size <= 0) { - /* Don't worry -- This is never hit unless it's a - blocking channel anyway */ - rc = libssh2_packet_read(session); + /* twiddle our thumbs until there's window space available */ + while (channel->local.window_size <= 0) { + /* Don't worry -- This is never hit unless it's a + blocking channel anyway */ + rc = libssh2_packet_read(session); - if (rc < 0) { - /* Error or EAGAIN occurred, disconnect? */ - return rc; - } + if (rc < 0) { + /* Error or EAGAIN occurred, disconnect? */ + return rc; + } - /* FIXME: (dast) if rc == 0 here then this busyloops - like hell until data arrives on the network which - seems like a very bad idea */ - } + /* FIXME: (dast) if rc == 0 here then this busyloops + like hell until data arrives on the network which + seems like a very bad idea */ + } - /* Don't exceed the remote end's limits */ - /* REMEMBER local means local as the SOURCE of the data */ - if (bufwrite > channel->local.window_size) { - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Splitting write block due to %lu byte window_size on %lu/%lu/%d", channel->local.window_size, channel->local.id, channel->remote.id, stream_id); - bufwrite = channel->local.window_size; - } - if (bufwrite > channel->local.packet_size) { - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Splitting write block due to %lu byte packet_size on %lu/%lu/%d", channel->local.packet_size, channel->local.id, channel->remote.id, stream_id); - bufwrite = channel->local.packet_size; - } - libssh2_htonu32(s, bufwrite); s += 4; - memcpy(s, buf, bufwrite); s += bufwrite; + /* Don't exceed the remote end's limits */ + /* REMEMBER local means local as the SOURCE of the data */ + if (bufwrite > channel->local.window_size) { + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Splitting write block due to %lu byte window_size on %lu/%lu/%d", channel->local.window_size, channel->local.id, channel->remote.id, stream_id); + bufwrite = channel->local.window_size; + } + if (bufwrite > channel->local.packet_size) { + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Splitting write block due to %lu byte packet_size on %lu/%lu/%d", channel->local.packet_size, channel->local.id, channel->remote.id, stream_id); + bufwrite = channel->local.packet_size; + } + libssh2_htonu32(s, bufwrite); s += 4; + memcpy(s, buf, bufwrite); s += bufwrite; - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending %d bytes on channel %lu/%lu, stream_id=%d", (int)bufwrite, channel->local.id, channel->remote.id, stream_id); - rc = libssh2_packet_write(session, packet, s - packet); - if(rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel data", 0); - LIBSSH2_FREE(session, packet); - return -1; - } - /* Shrink local window size */ - channel->local.window_size -= bufwrite; + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending %d bytes on channel %lu/%lu, stream_id=%d", (int)bufwrite, channel->local.id, channel->remote.id, stream_id); + rc = libssh2_packet_write(session, packet, s - packet); + if(rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel data", 0); + LIBSSH2_FREE(session, packet); + return -1; + } + /* Shrink local window size */ + channel->local.window_size -= bufwrite; - /* Adjust buf for next iteration */ - buflen -= bufwrite; - buf += bufwrite; - bufwrote += bufwrite; + /* Adjust buf for next iteration */ + buflen -= bufwrite; + buf += bufwrite; + bufwrote += bufwrite; - if (!channel->blocking) { - break; - } - } + if (!channel->blocking) { + break; + } + } - LIBSSH2_FREE(session, packet); + LIBSSH2_FREE(session, packet); - return bufwrote; + return bufwrote; } /* }}} */ @@ -1302,19 +1302,19 @@ int _libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, * Send data to a channel blocking */ LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, - int stream_id, - const char *buf, size_t buflen) + int stream_id, + const char *buf, size_t buflen) { - ssize_t rc; - /* set blocking */ - int bl = _libssh2_channel_set_blocking(channel, 1); + ssize_t rc; + /* set blocking */ + int bl = _libssh2_channel_set_blocking(channel, 1); - rc = _libssh2_channel_write_ex(channel, stream_id, buf, buflen); + rc = _libssh2_channel_write_ex(channel, stream_id, buf, buflen); - /* restore state */ - _libssh2_channel_set_blocking(channel, bl); + /* restore state */ + _libssh2_channel_set_blocking(channel, bl); - return rc; + return rc; } /* }}} */ @@ -1323,21 +1323,21 @@ LIBSSH2_API int libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, * Send data to a channel non-blocking */ LIBSSH2_API int libssh2_channel_writenb_ex(LIBSSH2_CHANNEL *channel, - int stream_id, - const char *buf, size_t buflen) + int stream_id, + const char *buf, size_t buflen) { - ssize_t rc; - int bl; + ssize_t rc; + int bl; - /* set non-blocking */ - bl = _libssh2_channel_set_blocking(channel, 0); + /* set non-blocking */ + bl = _libssh2_channel_set_blocking(channel, 0); - rc = _libssh2_channel_write_ex(channel, stream_id, buf, buflen); + rc = _libssh2_channel_write_ex(channel, stream_id, buf, buflen); - /* restore state */ - (void)_libssh2_channel_set_blocking(channel, bl); + /* restore state */ + (void)_libssh2_channel_set_blocking(channel, bl); - return rc; + return rc; } /* }}} */ @@ -1347,19 +1347,19 @@ LIBSSH2_API int libssh2_channel_writenb_ex(LIBSSH2_CHANNEL *channel, */ LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel) { - LIBSSH2_SESSION *session = channel->session; - unsigned char packet[5]; /* packet_type(1) + channelno(4) */ + LIBSSH2_SESSION *session = channel->session; + unsigned char packet[5]; /* packet_type(1) + channelno(4) */ - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending EOF on channel %lu/%lu",channel->local.id, channel->remote.id); - packet[0] = SSH_MSG_CHANNEL_EOF; - libssh2_htonu32(packet + 1, channel->remote.id); - if (libssh2_packet_write(session, packet, 5)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send EOF on channel", 0); - return -1; - } - channel->local.eof = 1; + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending EOF on channel %lu/%lu",channel->local.id, channel->remote.id); + packet[0] = SSH_MSG_CHANNEL_EOF; + libssh2_htonu32(packet + 1, channel->remote.id); + if (libssh2_packet_write(session, packet, 5)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send EOF on channel", 0); + return -1; + } + channel->local.eof = 1; - return 0; + return 0; } /* }}} */ @@ -1368,19 +1368,19 @@ LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel) */ LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel) { - LIBSSH2_SESSION *session = channel->session; - LIBSSH2_PACKET *packet = session->packets.head; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_PACKET *packet = session->packets.head; - while (packet) { - if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) || (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) && - (channel->local.id == libssh2_ntohu32(packet->data + 1))) { - /* There's data waiting to be read yet, mask the EOF status */ - return 0; - } - packet = packet->next; - } + while (packet) { + if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) || (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) && + (channel->local.id == libssh2_ntohu32(packet->data + 1))) { + /* There's data waiting to be read yet, mask the EOF status */ + return 0; + } + packet = packet->next; + } - return channel->remote.eof; + return channel->remote.eof; } /* }}} */ @@ -1389,45 +1389,45 @@ LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel) */ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel) { - LIBSSH2_SESSION *session = channel->session; - unsigned char packet[5]; - int rc = 0; + LIBSSH2_SESSION *session = channel->session; + unsigned char packet[5]; + int rc = 0; - if (channel->local.close) { - /* Already closed, act like we sent another close, even though we didn't... shhhhhh */ - return 0; - } + if (channel->local.close) { + /* Already closed, act like we sent another close, even though we didn't... shhhhhh */ + return 0; + } - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Closing channel %lu/%lu", channel->local.id, channel->remote.id); + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Closing channel %lu/%lu", channel->local.id, channel->remote.id); - if (channel->close_cb) { - LIBSSH2_CHANNEL_CLOSE(session, channel); - } - channel->local.close = 1; + if (channel->close_cb) { + LIBSSH2_CHANNEL_CLOSE(session, channel); + } + channel->local.close = 1; - packet[0] = SSH_MSG_CHANNEL_CLOSE; - libssh2_htonu32(packet + 1, channel->remote.id); - if (libssh2_packet_write(session, packet, 5)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send close-channel request", 0); - return -1; - } + packet[0] = SSH_MSG_CHANNEL_CLOSE; + libssh2_htonu32(packet + 1, channel->remote.id); + if (libssh2_packet_write(session, packet, 5)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send close-channel request", 0); + return -1; + } - /* We must wait for the remote SSH_MSG_CHANNEL_CLOSE message */ - if (!channel->remote.close) { - libssh2pack_t ret; - /* set blocking mode */ - int bl = _libssh2_channel_set_blocking(channel, 1); - do { - ret = libssh2_packet_read(session); - if ((ret < 0) && (ret != PACKET_EAGAIN)) { - rc = -1; - } - } while (ret != SSH_MSG_CHANNEL_CLOSE && rc == 0); + /* We must wait for the remote SSH_MSG_CHANNEL_CLOSE message */ + if (!channel->remote.close) { + libssh2pack_t ret; + /* set blocking mode */ + int bl = _libssh2_channel_set_blocking(channel, 1); + do { + ret = libssh2_packet_read(session); + if ((ret < 0) && (ret != PACKET_EAGAIN)) { + rc = -1; + } + } while (ret != SSH_MSG_CHANNEL_CLOSE && rc == 0); - _libssh2_channel_set_blocking(channel, bl); - } + _libssh2_channel_set_blocking(channel, bl); + } - return rc; + return rc; } /* }}} */ @@ -1436,24 +1436,24 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel) */ LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel) { - LIBSSH2_SESSION* session = channel->session; + LIBSSH2_SESSION* session = channel->session; - if (!libssh2_channel_eof(channel)) { - libssh2_error(session, LIBSSH2_ERROR_INVAL, "libssh2_channel_wait_closed() invoked when channel is not in EOF state", 0); - return -1; - } + if (!libssh2_channel_eof(channel)) { + libssh2_error(session, LIBSSH2_ERROR_INVAL, "libssh2_channel_wait_closed() invoked when channel is not in EOF state", 0); + return -1; + } - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Awaiting close of channel %lu/%lu", channel->local.id, channel->remote.id); + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Awaiting close of channel %lu/%lu", channel->local.id, channel->remote.id); - /* while channel is not closed, read more - * packets from the network. - * Either or channel will be closed - * or network timeout will occur - */ - while (!channel->remote.close && libssh2_packet_read(session) > 0) - ; + /* while channel is not closed, read more + * packets from the network. + * Either or channel will be closed + * or network timeout will occur + */ + while (!channel->remote.close && libssh2_packet_read(session) > 0) + ; - return 1; + return 1; } /* }}} */ @@ -1463,49 +1463,49 @@ LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel) */ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel) { - LIBSSH2_SESSION *session = channel->session; - unsigned char channel_id[4], *data; - unsigned long data_len; + LIBSSH2_SESSION *session = channel->session; + unsigned char channel_id[4], *data; + unsigned long data_len; - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Freeing channel %lu/%lu resources", channel->local.id, channel->remote.id); - /* Allow channel freeing even when the socket has lost its connection */ - if (!channel->local.close && (session->socket_state == LIBSSH2_SOCKET_CONNECTED) && - libssh2_channel_close(channel)) { - return -1; - } + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Freeing channel %lu/%lu resources", channel->local.id, channel->remote.id); + /* Allow channel freeing even when the socket has lost its connection */ + if (!channel->local.close && (session->socket_state == LIBSSH2_SOCKET_CONNECTED) && + libssh2_channel_close(channel)) { + return -1; + } - /* channel->remote.close *might* not be set yet, Well... - * We've sent the close packet, what more do you want? - * Just let packet_add ignore it when it finally arrives - */ + /* channel->remote.close *might* not be set yet, Well... + * We've sent the close packet, what more do you want? + * Just let packet_add ignore it when it finally arrives + */ - /* Clear out packets meant for this channel */ - libssh2_htonu32(channel_id, channel->local.id); - while ((libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_DATA, &data, &data_len, 1, channel_id, 4, 0) >= 0) || - (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data, &data_len, 1, channel_id, 4, 0) >= 0)) { - LIBSSH2_FREE(session, data); - } + /* Clear out packets meant for this channel */ + libssh2_htonu32(channel_id, channel->local.id); + while ((libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_DATA, &data, &data_len, 1, channel_id, 4, 0) >= 0) || + (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data, &data_len, 1, channel_id, 4, 0) >= 0)) { + LIBSSH2_FREE(session, data); + } - /* free "channel_type" */ - if (channel->channel_type) { - LIBSSH2_FREE(session, channel->channel_type); - } + /* free "channel_type" */ + if (channel->channel_type) { + LIBSSH2_FREE(session, channel->channel_type); + } - /* Unlink from channel brigade */ - if (channel->prev) { - channel->prev->next = channel->next; - } else { - session->channels.head = channel->next; - } - if (channel->next) { - channel->next->prev = channel->prev; - } else { - session->channels.tail = channel->prev; - } + /* Unlink from channel brigade */ + if (channel->prev) { + channel->prev->next = channel->next; + } else { + session->channels.head = channel->next; + } + if (channel->next) { + channel->next->prev = channel->prev; + } else { + session->channels.tail = channel->prev; + } - LIBSSH2_FREE(session, channel); + LIBSSH2_FREE(session, channel); - return 0; + return 0; } /* }}} */ @@ -1517,29 +1517,29 @@ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel) */ LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, unsigned long *read_avail, unsigned long *window_size_initial) { - if (window_size_initial) { - *window_size_initial = channel->remote.window_size_initial; - } + if (window_size_initial) { + *window_size_initial = channel->remote.window_size_initial; + } - if (read_avail) { - unsigned long bytes_queued = 0; - LIBSSH2_PACKET *packet = channel->session->packets.head; + if (read_avail) { + unsigned long bytes_queued = 0; + LIBSSH2_PACKET *packet = channel->session->packets.head; - while (packet) { - unsigned char packet_type = packet->data[0]; + while (packet) { + unsigned char packet_type = packet->data[0]; - if (((packet_type == SSH_MSG_CHANNEL_DATA) || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) && - (libssh2_ntohu32(packet->data + 1) == channel->local.id)) { - bytes_queued += packet->data_len - packet->data_head; - } + if (((packet_type == SSH_MSG_CHANNEL_DATA) || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) && + (libssh2_ntohu32(packet->data + 1) == channel->local.id)) { + bytes_queued += packet->data_len - packet->data_head; + } - packet = packet->next; - } + packet = packet->next; + } - *read_avail = bytes_queued; - } + *read_avail = bytes_queued; + } - return channel->remote.window_size; + return channel->remote.window_size; } /* }}} */ @@ -1550,11 +1550,11 @@ LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channe */ LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial) { - if (window_size_initial) { - /* For locally initiated channels this is very often 0, so it's not *that* useful as information goes */ - *window_size_initial = channel->local.window_size_initial; - } + if (window_size_initial) { + /* For locally initiated channels this is very often 0, so it's not *that* useful as information goes */ + *window_size_initial = channel->local.window_size_initial; + } - return channel->local.window_size; + return channel->local.window_size; } /* }}} */ diff --git a/src/comp.c b/src/comp.c index 3b98c5b..558ddf7 100644 --- a/src/comp.c +++ b/src/comp.c @@ -48,33 +48,33 @@ * Minimalist compression: Absolutely none */ static int libssh2_comp_method_none_comp(LIBSSH2_SESSION *session, - int compress, - unsigned char **dest, - unsigned long *dest_len, - unsigned long payload_limit, - int *free_dest, - const unsigned char *src, - unsigned long src_len, - void **abstract) + int compress, + unsigned char **dest, + unsigned long *dest_len, + unsigned long payload_limit, + int *free_dest, + const unsigned char *src, + unsigned long src_len, + void **abstract) { - (void)session; - (void)compress; - (void)payload_limit; - (void)abstract; - *dest = (unsigned char *)src; - *dest_len = src_len; + (void)session; + (void)compress; + (void)payload_limit; + (void)abstract; + *dest = (unsigned char *)src; + *dest_len = src_len; - *free_dest = 0; + *free_dest = 0; - return 0; + return 0; } /* }}} */ static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = { - "none", - NULL, - libssh2_comp_method_none_comp, - NULL + "none", + NULL, + libssh2_comp_method_none_comp, + NULL }; #ifdef LIBSSH2_HAVE_ZLIB @@ -89,16 +89,16 @@ static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = { static voidpf libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size) { - LIBSSH2_SESSION *session = (LIBSSH2_SESSION*)opaque; + LIBSSH2_SESSION *session = (LIBSSH2_SESSION*)opaque; - return (voidpf)LIBSSH2_ALLOC(session, items * size); + return (voidpf)LIBSSH2_ALLOC(session, items * size); } static void libssh2_comp_method_zlib_free(voidpf opaque, voidpf address) { - LIBSSH2_SESSION *session = (LIBSSH2_SESSION*)opaque; + LIBSSH2_SESSION *session = (LIBSSH2_SESSION*)opaque; - LIBSSH2_FREE(session, address); + LIBSSH2_FREE(session, address); } /* }}} */ @@ -107,34 +107,34 @@ static void libssh2_comp_method_zlib_free(voidpf opaque, voidpf address) */ static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress, void **abstract) { - z_stream *strm; - int status; + z_stream *strm; + int status; - strm = LIBSSH2_ALLOC(session, sizeof(z_stream)); - if (!strm) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for zlib compression/decompression", 0); - return -1; - } - memset(strm, 0, sizeof(z_stream)); + strm = LIBSSH2_ALLOC(session, sizeof(z_stream)); + if (!strm) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for zlib compression/decompression", 0); + return -1; + } + memset(strm, 0, sizeof(z_stream)); - strm->opaque = (voidpf)session; - strm->zalloc = (alloc_func)libssh2_comp_method_zlib_alloc; - strm->zfree = (free_func)libssh2_comp_method_zlib_free; - if (compress) { - /* deflate */ - status = deflateInit(strm, Z_DEFAULT_COMPRESSION); - } else { - /* inflate */ - status = inflateInit(strm); - } + strm->opaque = (voidpf)session; + strm->zalloc = (alloc_func)libssh2_comp_method_zlib_alloc; + strm->zfree = (free_func)libssh2_comp_method_zlib_free; + if (compress) { + /* deflate */ + status = deflateInit(strm, Z_DEFAULT_COMPRESSION); + } else { + /* inflate */ + status = inflateInit(strm); + } - if (status != Z_OK) { - LIBSSH2_FREE(session, strm); - return -1; - } - *abstract = strm; + if (status != Z_OK) { + LIBSSH2_FREE(session, strm); + return -1; + } + *abstract = strm; - return 0; + return 0; } /* }}} */ @@ -142,124 +142,124 @@ static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress, * zlib, a compression standard for all occasions */ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session, - int compress, - unsigned char **dest, - unsigned long *dest_len, - unsigned long payload_limit, - int *free_dest, - const unsigned char *src, - unsigned long src_len, - void **abstract) + int compress, + unsigned char **dest, + unsigned long *dest_len, + unsigned long payload_limit, + int *free_dest, + const unsigned char *src, + unsigned long src_len, + void **abstract) { - z_stream *strm = *abstract; - /* A short-term alloc of a full data chunk is better than a series of - reallocs */ - char *out; - int out_maxlen = compress ? (src_len + 4) : (2 * src_len); - int limiter = 0; + z_stream *strm = *abstract; + /* A short-term alloc of a full data chunk is better than a series of + reallocs */ + char *out; + int out_maxlen = compress ? (src_len + 4) : (2 * src_len); + int limiter = 0; - /* In practice they never come smaller than this */ - if (out_maxlen < 25) { - out_maxlen = 25; - } + /* In practice they never come smaller than this */ + if (out_maxlen < 25) { + out_maxlen = 25; + } - if (out_maxlen > (int)payload_limit) { - out_maxlen = payload_limit; - } + if (out_maxlen > (int)payload_limit) { + out_maxlen = payload_limit; + } - strm->next_in = (unsigned char *)src; - strm->avail_in = src_len; - strm->next_out = (unsigned char *)LIBSSH2_ALLOC(session, out_maxlen); - out = (char *)strm->next_out; - strm->avail_out = out_maxlen; - if (!strm->next_out) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate compression/decompression buffer", 0); - return -1; - } - while (strm->avail_in) { - int status; + strm->next_in = (unsigned char *)src; + strm->avail_in = src_len; + strm->next_out = (unsigned char *)LIBSSH2_ALLOC(session, out_maxlen); + out = (char *)strm->next_out; + strm->avail_out = out_maxlen; + if (!strm->next_out) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate compression/decompression buffer", 0); + return -1; + } + while (strm->avail_in) { + int status; - if (compress) { - status = deflate(strm, Z_PARTIAL_FLUSH); - } else { - status = inflate(strm, Z_PARTIAL_FLUSH); - } - if (status != Z_OK) { - libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0); - LIBSSH2_FREE(session, out); - return -1; - } - if (strm->avail_in) { - unsigned long out_ofs = out_maxlen - strm->avail_out; - char *newout; + if (compress) { + status = deflate(strm, Z_PARTIAL_FLUSH); + } else { + status = inflate(strm, Z_PARTIAL_FLUSH); + } + if (status != Z_OK) { + libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0); + LIBSSH2_FREE(session, out); + return -1; + } + if (strm->avail_in) { + unsigned long out_ofs = out_maxlen - strm->avail_out; + char *newout; - out_maxlen += compress ? (strm->avail_in + 4) : (2 * strm->avail_in); + out_maxlen += compress ? (strm->avail_in + 4) : (2 * strm->avail_in); - if ((out_maxlen > (int)payload_limit) && - !compress && limiter++) { - libssh2_error(session, LIBSSH2_ERROR_ZLIB, - "Excessive growth in decompression phase", 0); - LIBSSH2_FREE(session, out); - return -1; - } + if ((out_maxlen > (int)payload_limit) && + !compress && limiter++) { + libssh2_error(session, LIBSSH2_ERROR_ZLIB, + "Excessive growth in decompression phase", 0); + LIBSSH2_FREE(session, out); + return -1; + } - newout = LIBSSH2_REALLOC(session, out, out_maxlen); - if (!newout) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand compress/decompression buffer", 0); - LIBSSH2_FREE(session, out); - return -1; - } - out = newout; - strm->next_out = (unsigned char *)out + out_ofs; - strm->avail_out += compress ? (strm->avail_in + 4) : (2 * strm->avail_in); - } else while (!strm->avail_out) { - /* Done with input, might be a byte or two in internal buffer during compress - * Or potentially many bytes if it's a decompress - */ - int grow_size = compress ? 8 : 1024; - char *newout; + newout = LIBSSH2_REALLOC(session, out, out_maxlen); + if (!newout) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand compress/decompression buffer", 0); + LIBSSH2_FREE(session, out); + return -1; + } + out = newout; + strm->next_out = (unsigned char *)out + out_ofs; + strm->avail_out += compress ? (strm->avail_in + 4) : (2 * strm->avail_in); + } else while (!strm->avail_out) { + /* Done with input, might be a byte or two in internal buffer during compress + * Or potentially many bytes if it's a decompress + */ + int grow_size = compress ? 8 : 1024; + char *newout; - if (out_maxlen >= (int)payload_limit) { - libssh2_error(session, LIBSSH2_ERROR_ZLIB, "Excessive growth in decompression phase", 0); - LIBSSH2_FREE(session, out); - return -1; - } + if (out_maxlen >= (int)payload_limit) { + libssh2_error(session, LIBSSH2_ERROR_ZLIB, "Excessive growth in decompression phase", 0); + LIBSSH2_FREE(session, out); + return -1; + } - if (grow_size > (int)(payload_limit - out_maxlen)) { - grow_size = payload_limit - out_maxlen; - } + if (grow_size > (int)(payload_limit - out_maxlen)) { + grow_size = payload_limit - out_maxlen; + } - out_maxlen += grow_size; - strm->avail_out = grow_size; + out_maxlen += grow_size; + strm->avail_out = grow_size; - newout = LIBSSH2_REALLOC(session, out, out_maxlen); - if (!newout) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand final compress/decompress buffer", 0); - LIBSSH2_FREE(session, out); - return -1; - } - out = newout; - strm->next_out = (unsigned char *)out + out_maxlen - - grow_size; + newout = LIBSSH2_REALLOC(session, out, out_maxlen); + if (!newout) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to expand final compress/decompress buffer", 0); + LIBSSH2_FREE(session, out); + return -1; + } + out = newout; + strm->next_out = (unsigned char *)out + out_maxlen - + grow_size; - if (compress) { - status = deflate(strm, Z_PARTIAL_FLUSH); - } else { - status = inflate(strm, Z_PARTIAL_FLUSH); - } - if (status != Z_OK) { - libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0); - LIBSSH2_FREE(session, out); - return -1; - } - } - } + if (compress) { + status = deflate(strm, Z_PARTIAL_FLUSH); + } else { + status = inflate(strm, Z_PARTIAL_FLUSH); + } + if (status != Z_OK) { + libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0); + LIBSSH2_FREE(session, out); + return -1; + } + } + } - *dest = (unsigned char *)out; - *dest_len = out_maxlen - strm->avail_out; - *free_dest = 1; + *dest = (unsigned char *)out; + *dest_len = out_maxlen - strm->avail_out; + *free_dest = 1; - return 0; + return 0; } /* }}} */ @@ -268,31 +268,31 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session, */ static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress, void **abstract) { - z_stream *strm = *abstract; + z_stream *strm = *abstract; - if (strm) { - if (compress) { - /* deflate */ - deflateEnd(strm); - } else { - /* inflate */ - inflateEnd(strm); - } + if (strm) { + if (compress) { + /* deflate */ + deflateEnd(strm); + } else { + /* inflate */ + inflateEnd(strm); + } - LIBSSH2_FREE(session, strm); - } + LIBSSH2_FREE(session, strm); + } - *abstract = NULL; + *abstract = NULL; - return 0; + return 0; } /* }}} */ static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = { - "zlib", - libssh2_comp_method_zlib_init, - libssh2_comp_method_zlib_comp, - libssh2_comp_method_zlib_dtor, + "zlib", + libssh2_comp_method_zlib_init, + libssh2_comp_method_zlib_comp, + libssh2_comp_method_zlib_dtor, }; #endif /* LIBSSH2_HAVE_ZLIB */ @@ -301,14 +301,14 @@ static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = { *********************** */ static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = { - &libssh2_comp_method_none, + &libssh2_comp_method_none, #ifdef LIBSSH2_HAVE_ZLIB - &libssh2_comp_method_zlib, + &libssh2_comp_method_zlib, #endif /* LIBSSH2_HAVE_ZLIB */ - NULL + NULL }; const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void) { - return _libssh2_comp_methods; + return _libssh2_comp_methods; } diff --git a/src/crypt.c b/src/crypt.c index c8f1dbf..9ab1cab 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -43,205 +43,205 @@ */ static int libssh2_crypt_none_crypt(LIBSSH2_SESSION *session, unsigned char *buf, void **abstract) { - /* Do nothing to the data! */ - return 0; + /* Do nothing to the data! */ + return 0; } /* }}} */ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = { - "none", - 8, /* blocksize (SSH2 defines minimum blocksize as 8) */ - 0, /* iv_len */ - 0, /* secret_len */ - 0, /* flags */ - NULL, - libssh2_crypt_none_crypt, - NULL + "none", + 8, /* blocksize (SSH2 defines minimum blocksize as 8) */ + 0, /* iv_len */ + 0, /* secret_len */ + 0, /* flags */ + NULL, + libssh2_crypt_none_crypt, + NULL }; #endif /* LIBSSH2_CRYPT_NONE */ struct crypt_ctx { - int encrypt; - _libssh2_cipher_type(algo); - _libssh2_cipher_ctx h; + int encrypt; + _libssh2_cipher_type(algo); + _libssh2_cipher_ctx h; }; static int _libssh2_init (LIBSSH2_SESSION *session, - const LIBSSH2_CRYPT_METHOD *method, - unsigned char *iv, int *free_iv, - unsigned char *secret, int *free_secret, - int encrypt, void **abstract) + const LIBSSH2_CRYPT_METHOD *method, + unsigned char *iv, int *free_iv, + unsigned char *secret, int *free_secret, + int encrypt, void **abstract) { - struct crypt_ctx *ctx = LIBSSH2_ALLOC(session, - sizeof(struct crypt_ctx)); - if (!ctx) { - return -1; - } - ctx->encrypt = encrypt; - ctx->algo = method->algo; - if (_libssh2_cipher_init (&ctx->h, ctx->algo, iv, secret, encrypt)) - { - LIBSSH2_FREE (session, ctx); - return -1; - } - *abstract = ctx; - *free_iv = 1; - *free_secret = 1; - return 0; + struct crypt_ctx *ctx = LIBSSH2_ALLOC(session, + sizeof(struct crypt_ctx)); + if (!ctx) { + return -1; + } + ctx->encrypt = encrypt; + ctx->algo = method->algo; + if (_libssh2_cipher_init (&ctx->h, ctx->algo, iv, secret, encrypt)) + { + LIBSSH2_FREE (session, ctx); + return -1; + } + *abstract = ctx; + *free_iv = 1; + *free_secret = 1; + return 0; } static int _libssh2_encrypt(LIBSSH2_SESSION *session, unsigned char *block, void **abstract) { - struct crypt_ctx *cctx = *(struct crypt_ctx **)abstract; - (void)session; - return _libssh2_cipher_crypt(&cctx->h, cctx->algo, - cctx->encrypt, block); + struct crypt_ctx *cctx = *(struct crypt_ctx **)abstract; + (void)session; + return _libssh2_cipher_crypt(&cctx->h, cctx->algo, + cctx->encrypt, block); } static int _libssh2_dtor(LIBSSH2_SESSION *session, void **abstract) { - struct crypt_ctx **cctx = (struct crypt_ctx **)abstract; - if (cctx && *cctx) { - _libssh2_cipher_dtor(&(*cctx)->h); - LIBSSH2_FREE(session, *cctx); - *abstract = NULL; - } - return 0; + struct crypt_ctx **cctx = (struct crypt_ctx **)abstract; + if (cctx && *cctx) { + _libssh2_cipher_dtor(&(*cctx)->h); + LIBSSH2_FREE(session, *cctx); + *abstract = NULL; + } + return 0; } #if LIBSSH2_AES static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = { - "aes128-cbc", - 16, /* blocksize */ - 16, /* initial value length */ - 16, /* secret length -- 16*8 == 128bit */ - 0, /* flags */ - &_libssh2_init, - &_libssh2_encrypt, - &_libssh2_dtor, - _libssh2_cipher_aes128 + "aes128-cbc", + 16, /* blocksize */ + 16, /* initial value length */ + 16, /* secret length -- 16*8 == 128bit */ + 0, /* flags */ + &_libssh2_init, + &_libssh2_encrypt, + &_libssh2_dtor, + _libssh2_cipher_aes128 }; static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = { - "aes192-cbc", - 16, /* blocksize */ - 16, /* initial value length */ - 24, /* secret length -- 24*8 == 192bit */ - 0, /* flags */ - &_libssh2_init, - &_libssh2_encrypt, - &_libssh2_dtor, - _libssh2_cipher_aes192 + "aes192-cbc", + 16, /* blocksize */ + 16, /* initial value length */ + 24, /* secret length -- 24*8 == 192bit */ + 0, /* flags */ + &_libssh2_init, + &_libssh2_encrypt, + &_libssh2_dtor, + _libssh2_cipher_aes192 }; static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = { - "aes256-cbc", - 16, /* blocksize */ - 16, /* initial value length */ - 32, /* secret length -- 32*8 == 256bit */ - 0, /* flags */ - &_libssh2_init, - &_libssh2_encrypt, - &_libssh2_dtor, - _libssh2_cipher_aes256 + "aes256-cbc", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &_libssh2_init, + &_libssh2_encrypt, + &_libssh2_dtor, + _libssh2_cipher_aes256 }; /* rijndael-cbc@lysator.liu.se == aes256-cbc */ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_rijndael_cbc_lysator_liu_se = { - "rijndael-cbc@lysator.liu.se", - 16, /* blocksize */ - 16, /* initial value length */ - 32, /* secret length -- 32*8 == 256bit */ - 0, /* flags */ - &_libssh2_init, - &_libssh2_encrypt, - &_libssh2_dtor, - _libssh2_cipher_aes256 + "rijndael-cbc@lysator.liu.se", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &_libssh2_init, + &_libssh2_encrypt, + &_libssh2_dtor, + _libssh2_cipher_aes256 }; #endif /* LIBSSH2_AES */ #if LIBSSH2_BLOWFISH static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = { - "blowfish-cbc", - 8, /* blocksize */ - 8, /* initial value length */ - 16, /* secret length */ - 0, /* flags */ - &_libssh2_init, - &_libssh2_encrypt, - &_libssh2_dtor, - _libssh2_cipher_blowfish + "blowfish-cbc", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &_libssh2_init, + &_libssh2_encrypt, + &_libssh2_dtor, + _libssh2_cipher_blowfish }; #endif /* LIBSSH2_BLOWFISH */ #if LIBSSH2_RC4 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = { - "arcfour", - 8, /* blocksize */ - 8, /* initial value length */ - 16, /* secret length */ - 0, /* flags */ - &_libssh2_init, - &_libssh2_encrypt, - &_libssh2_dtor, - _libssh2_cipher_arcfour + "arcfour", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &_libssh2_init, + &_libssh2_encrypt, + &_libssh2_dtor, + _libssh2_cipher_arcfour }; #endif /* LIBSSH2_RC4 */ #if LIBSSH2_CAST static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = { - "cast128-cbc", - 8, /* blocksize */ - 8, /* initial value length */ - 16, /* secret length */ - 0, /* flags */ - &_libssh2_init, - &_libssh2_encrypt, - &_libssh2_dtor, - _libssh2_cipher_cast5 + "cast128-cbc", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &_libssh2_init, + &_libssh2_encrypt, + &_libssh2_dtor, + _libssh2_cipher_cast5 }; #endif /* LIBSSH2_CAST */ #if LIBSSH2_3DES static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = { - "3des-cbc", - 8, /* blocksize */ - 8, /* initial value length */ - 24, /* secret length */ - 0, /* flags */ - &_libssh2_init, - &_libssh2_encrypt, - &_libssh2_dtor, - _libssh2_cipher_3des + "3des-cbc", + 8, /* blocksize */ + 8, /* initial value length */ + 24, /* secret length */ + 0, /* flags */ + &_libssh2_init, + &_libssh2_encrypt, + &_libssh2_dtor, + _libssh2_cipher_3des }; #endif static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = { #if LIBSSH2_AES - &libssh2_crypt_method_aes256_cbc, - &libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */ - &libssh2_crypt_method_aes192_cbc, - &libssh2_crypt_method_aes128_cbc, + &libssh2_crypt_method_aes256_cbc, + &libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */ + &libssh2_crypt_method_aes192_cbc, + &libssh2_crypt_method_aes128_cbc, #endif /* LIBSSH2_AES */ #if LIBSSH2_BLOWFISH - &libssh2_crypt_method_blowfish_cbc, + &libssh2_crypt_method_blowfish_cbc, #endif /* LIBSSH2_BLOWFISH */ #if LIBSSH2_RC4 - &libssh2_crypt_method_arcfour, + &libssh2_crypt_method_arcfour, #endif /* LIBSSH2_RC4 */ #if LIBSSH2_CAST - &libssh2_crypt_method_cast128_cbc, + &libssh2_crypt_method_cast128_cbc, #endif /* LIBSSH2_CAST */ #if LIBSSH2_3DES - &libssh2_crypt_method_3des_cbc, + &libssh2_crypt_method_3des_cbc, #endif /* LIBSSH2_DES */ #ifdef LIBSSH2_CRYPT_NONE - &libssh2_crypt_method_none, + &libssh2_crypt_method_none, #endif - NULL + NULL }; /* Expose to kex.c */ const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void) { - return _libssh2_crypt_methods; + return _libssh2_crypt_methods; } diff --git a/src/hostkey.c b/src/hostkey.c index a3d6180..d1dbbd6 100644 --- a/src/hostkey.c +++ b/src/hostkey.c @@ -54,44 +54,44 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, void ** */ static int libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session, - const unsigned char *hostkey_data, - unsigned long hostkey_data_len, - void **abstract) + const unsigned char *hostkey_data, + unsigned long hostkey_data_len, + void **abstract) { - libssh2_rsa_ctx *rsactx; - const unsigned char *s, *e, *n; - unsigned long len, e_len, n_len; + libssh2_rsa_ctx *rsactx; + const unsigned char *s, *e, *n; + unsigned long len, e_len, n_len; - (void)hostkey_data_len; + (void)hostkey_data_len; - if (*abstract) { - libssh2_hostkey_method_ssh_rsa_dtor(session, abstract); - *abstract = NULL; - } + if (*abstract) { + libssh2_hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } - s = hostkey_data; - len = libssh2_ntohu32(s); - s += 4; + s = hostkey_data; + len = libssh2_ntohu32(s); + s += 4; - if (len != 7 || strncmp((char *)s, "ssh-rsa", 7) != 0) { - return -1; - } - s += 7; + if (len != 7 || strncmp((char *)s, "ssh-rsa", 7) != 0) { + return -1; + } + s += 7; - e_len = libssh2_ntohu32(s); - s += 4; + e_len = libssh2_ntohu32(s); + s += 4; - e = s; s += e_len; - n_len = libssh2_ntohu32(s); s += 4; - n = s; s += n_len; + e = s; s += e_len; + n_len = libssh2_ntohu32(s); s += 4; + n = s; s += n_len; - if (_libssh2_rsa_new (&rsactx, e, e_len, n, n_len, NULL, 0, - NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0)) - return -1; + if (_libssh2_rsa_new (&rsactx, e, e_len, n, n_len, NULL, 0, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0)) + return -1; - *abstract = rsactx; + *abstract = rsactx; - return 0; + return 0; } /* }}} */ @@ -99,31 +99,31 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session, * Load a Private Key from a PEM file */ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session, - const char *privkeyfile, unsigned const char *passphrase, void **abstract) + const char *privkeyfile, unsigned const char *passphrase, void **abstract) { - libssh2_rsa_ctx *rsactx; - FILE *fp; - int ret; + libssh2_rsa_ctx *rsactx; + FILE *fp; + int ret; - if (*abstract) { - libssh2_hostkey_method_ssh_rsa_dtor(session, abstract); - *abstract = NULL; - } + if (*abstract) { + libssh2_hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } - fp = fopen(privkeyfile, "r"); - if (!fp) { - return -1; - } + fp = fopen(privkeyfile, "r"); + if (!fp) { + return -1; + } - ret = _libssh2_rsa_new_private (&rsactx, session, fp, passphrase); - fclose(fp); - if (ret) { - return -1; - } + ret = _libssh2_rsa_new_private (&rsactx, session, fp, passphrase); + fclose(fp); + if (ret) { + return -1; + } - *abstract = rsactx; + *abstract = rsactx; - return 0; + return 0; } /* }}} */ @@ -131,18 +131,18 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session, * Verify signature created by remote */ static int libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION *session, - const unsigned char *sig, - unsigned long sig_len, - const unsigned char *m, - unsigned long m_len, - void **abstract) + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len, + void **abstract) { - libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); - (void)session; + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); + (void)session; - /* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */ - sig += 15; sig_len -= 15; - return _libssh2_rsa_sha1_verify (rsactx, sig, sig_len, m, m_len); + /* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */ + sig += 15; sig_len -= 15; + return _libssh2_rsa_sha1_verify (rsactx, sig, sig_len, m, m_len); } /* }}} */ @@ -150,27 +150,27 @@ static int libssh2_hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION *session, * Construct a signature from an array of vectors */ static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, - unsigned long veccount, const struct iovec datavec[], void **abstract) + unsigned long veccount, const struct iovec datavec[], void **abstract) { - libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); - int ret; - unsigned int i; - unsigned char hash[SHA_DIGEST_LENGTH]; - libssh2_sha1_ctx ctx; + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); + int ret; + unsigned int i; + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_sha1_ctx ctx; - libssh2_sha1_init(&ctx); - for(i = 0; i < veccount; i++) { - libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); - } - libssh2_sha1_final(ctx, hash); + libssh2_sha1_init(&ctx); + for(i = 0; i < veccount; i++) { + libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + } + libssh2_sha1_final(ctx, hash); - ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, - signature, signature_len); - if (ret) { - return -1; - } + ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, + signature, signature_len); + if (ret) { + return -1; + } - return 0; + return 0; } /* }}} */ @@ -178,28 +178,28 @@ static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsign * Shutdown the hostkey */ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, - void **abstract) + void **abstract) { - libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); - (void)session; + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); + (void)session; - _libssh2_rsa_free(rsactx); + _libssh2_rsa_free(rsactx); - *abstract = NULL; + *abstract = NULL; - return 0; + return 0; } /* }}} */ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = { - "ssh-rsa", - MD5_DIGEST_LENGTH, - libssh2_hostkey_method_ssh_rsa_init, - libssh2_hostkey_method_ssh_rsa_initPEM, - libssh2_hostkey_method_ssh_rsa_sig_verify, - libssh2_hostkey_method_ssh_rsa_signv, - NULL, /* encrypt */ - libssh2_hostkey_method_ssh_rsa_dtor, + "ssh-rsa", + MD5_DIGEST_LENGTH, + libssh2_hostkey_method_ssh_rsa_init, + libssh2_hostkey_method_ssh_rsa_initPEM, + libssh2_hostkey_method_ssh_rsa_sig_verify, + libssh2_hostkey_method_ssh_rsa_signv, + NULL, /* encrypt */ + libssh2_hostkey_method_ssh_rsa_dtor, }; #endif /* LIBSSH2_RSA */ @@ -215,41 +215,41 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, void ** */ static int libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session, - const unsigned char *hostkey_data, - unsigned long hostkey_data_len, - void **abstract) + const unsigned char *hostkey_data, + unsigned long hostkey_data_len, + void **abstract) { - libssh2_dsa_ctx *dsactx; - const unsigned char *p, *q, *g, *y, *s; - unsigned long p_len, q_len, g_len, y_len, len; - (void)hostkey_data_len; + libssh2_dsa_ctx *dsactx; + const unsigned char *p, *q, *g, *y, *s; + unsigned long p_len, q_len, g_len, y_len, len; + (void)hostkey_data_len; - if (*abstract) { - libssh2_hostkey_method_ssh_dss_dtor(session, abstract); - *abstract = NULL; - } + if (*abstract) { + libssh2_hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } - s = hostkey_data; - len = libssh2_ntohu32(s); s += 4; - if (len != 7 || strncmp((char *)s, "ssh-dss", 7) != 0) { - return -1; - } s += 7; + s = hostkey_data; + len = libssh2_ntohu32(s); s += 4; + if (len != 7 || strncmp((char *)s, "ssh-dss", 7) != 0) { + return -1; + } s += 7; - p_len = libssh2_ntohu32(s); s += 4; - p = s; s += p_len; - q_len = libssh2_ntohu32(s); s += 4; - q = s; s += q_len; - g_len = libssh2_ntohu32(s); s += 4; - g = s; s += g_len; - y_len = libssh2_ntohu32(s); s += 4; - y = s; s += y_len; + p_len = libssh2_ntohu32(s); s += 4; + p = s; s += p_len; + q_len = libssh2_ntohu32(s); s += 4; + q = s; s += q_len; + g_len = libssh2_ntohu32(s); s += 4; + g = s; s += g_len; + y_len = libssh2_ntohu32(s); s += 4; + y = s; s += y_len; - _libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, - y, y_len, NULL, 0); + _libssh2_dsa_new(&dsactx, p, p_len, q, q_len, g, g_len, + y, y_len, NULL, 0); - *abstract = dsactx; + *abstract = dsactx; - return 0; + return 0; } /* }}} */ @@ -257,33 +257,33 @@ libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session, * Load a Private Key from a PEM file */ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session, - const char *privkeyfile, - unsigned const char *passphrase, - void **abstract) + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) { - libssh2_dsa_ctx *dsactx; - FILE *fp; - int ret; + libssh2_dsa_ctx *dsactx; + FILE *fp; + int ret; - if (*abstract) { - libssh2_hostkey_method_ssh_dss_dtor(session, abstract); - *abstract = NULL; - } + if (*abstract) { + libssh2_hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } - fp = fopen(privkeyfile, "r"); - if (!fp) { - return -1; - } + fp = fopen(privkeyfile, "r"); + if (!fp) { + return -1; + } - ret = _libssh2_dsa_new_private (&dsactx, session, fp, passphrase); - fclose(fp); - if (ret) { - return -1; - } + ret = _libssh2_dsa_new_private (&dsactx, session, fp, passphrase); + fclose(fp); + if (ret) { + return -1; + } - *abstract = dsactx; + *abstract = dsactx; - return 0; + return 0; } /* }}} */ @@ -291,17 +291,17 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session, * Verify signature created by remote */ static int libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, - const unsigned char *m, unsigned long m_len, void **abstract) + const unsigned char *m, unsigned long m_len, void **abstract) { - libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); - /* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */ - sig += 15; sig_len -= 15; - if (sig_len != 40) { - libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid DSS signature length", 0); - return -1; - } - return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len); + /* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */ + sig += 15; sig_len -= 15; + if (sig_len != 40) { + libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid DSS signature length", 0); + return -1; + } + return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len); } /* }}} */ @@ -309,35 +309,35 @@ static int libssh2_hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION *session, c * Construct a signature from an array of vectors */ static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, - unsigned long veccount, const struct iovec datavec[], void **abstract) + unsigned long veccount, const struct iovec datavec[], void **abstract) { - libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); - unsigned char hash[SHA_DIGEST_LENGTH]; - libssh2_sha1_ctx ctx; - unsigned int i; + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_sha1_ctx ctx; + unsigned int i; - *signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH); - if (!*signature) { - return -1; - } + *signature = LIBSSH2_ALLOC(session, 2 * SHA_DIGEST_LENGTH); + if (!*signature) { + return -1; + } - *signature_len = 2 * SHA_DIGEST_LENGTH; - memset(*signature, 0, 2 * SHA_DIGEST_LENGTH); + *signature_len = 2 * SHA_DIGEST_LENGTH; + memset(*signature, 0, 2 * SHA_DIGEST_LENGTH); - libssh2_sha1_init(&ctx); - for(i = 0; i < veccount; i++) { - libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); - } - libssh2_sha1_final(ctx, hash); + libssh2_sha1_init(&ctx); + for(i = 0; i < veccount; i++) { + libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + } + libssh2_sha1_final(ctx, hash); - if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, - *signature)) - { - LIBSSH2_FREE(session, *signature); - return -1; - } + if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, + *signature)) + { + LIBSSH2_FREE(session, *signature); + return -1; + } - return 0; + return 0; } /* }}} */ @@ -345,44 +345,44 @@ static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsign * Shutdown the hostkey method */ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, - void **abstract) + void **abstract) { - libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); - (void)session; + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); + (void)session; - _libssh2_dsa_free(dsactx); + _libssh2_dsa_free(dsactx); - *abstract = NULL; + *abstract = NULL; - return 0; + return 0; } /* }}} */ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = { - "ssh-dss", - MD5_DIGEST_LENGTH, - libssh2_hostkey_method_ssh_dss_init, - libssh2_hostkey_method_ssh_dss_initPEM, - libssh2_hostkey_method_ssh_dss_sig_verify, - libssh2_hostkey_method_ssh_dss_signv, - NULL, /* encrypt */ - libssh2_hostkey_method_ssh_dss_dtor, + "ssh-dss", + MD5_DIGEST_LENGTH, + libssh2_hostkey_method_ssh_dss_init, + libssh2_hostkey_method_ssh_dss_initPEM, + libssh2_hostkey_method_ssh_dss_sig_verify, + libssh2_hostkey_method_ssh_dss_signv, + NULL, /* encrypt */ + libssh2_hostkey_method_ssh_dss_dtor, }; #endif /* LIBSSH2_DSA */ static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = { #if LIBSSH2_RSA - &libssh2_hostkey_method_ssh_rsa, + &libssh2_hostkey_method_ssh_rsa, #endif /* LIBSSH2_RSA */ #if LIBSSH2_DSA - &libssh2_hostkey_method_ssh_dss, + &libssh2_hostkey_method_ssh_dss, #endif /* LIBSSH2_DSA */ - NULL + NULL }; const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void) { - return _libssh2_hostkey_methods; + return _libssh2_hostkey_methods; } /* {{{ libssh2_hostkey_hash @@ -393,18 +393,18 @@ const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void) */ LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type) { - switch (hash_type) { + switch (hash_type) { #if LIBSSH2_MD5 - case LIBSSH2_HOSTKEY_HASH_MD5: - return (char *)session->server_hostkey_md5; - break; + case LIBSSH2_HOSTKEY_HASH_MD5: + return (char *)session->server_hostkey_md5; + break; #endif /* LIBSSH2_MD5 */ - case LIBSSH2_HOSTKEY_HASH_SHA1: - return (char *)session->server_hostkey_sha1; - break; - default: - return NULL; - } + case LIBSSH2_HOSTKEY_HASH_SHA1: + return (char *)session->server_hostkey_sha1; + break; + default: + return NULL; + } } /* }}} */ diff --git a/src/kex.c b/src/kex.c index df045e8..7c1e6e1 100644 --- a/src/kex.c +++ b/src/kex.c @@ -39,440 +39,440 @@ /* TODO: Switch this to an inline and handle alloc() failures */ /* Helper macro called from libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange */ -#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \ -{ \ - libssh2_sha1_ctx hash; \ - unsigned long len = 0; \ - if (!(value)) { \ - value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \ - } \ - if (value) \ - while (len < reqlen) { \ - libssh2_sha1_init(&hash); \ - libssh2_sha1_update(hash, k_value, k_value_len); \ - libssh2_sha1_update(hash, h_sig_comp, SHA_DIGEST_LENGTH); \ - if (len > 0) { \ - libssh2_sha1_update(hash, value, len); \ - } else { \ - libssh2_sha1_update(hash, (version), 1); \ - libssh2_sha1_update(hash, session->session_id, session->session_id_len); \ - } \ - libssh2_sha1_final(hash, (value) + len); \ - len += SHA_DIGEST_LENGTH; \ - } \ +#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \ +{ \ + libssh2_sha1_ctx hash; \ + unsigned long len = 0; \ + if (!(value)) { \ + value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \ + } \ + if (value) \ + while (len < reqlen) { \ + libssh2_sha1_init(&hash); \ + libssh2_sha1_update(hash, k_value, k_value_len); \ + libssh2_sha1_update(hash, h_sig_comp, SHA_DIGEST_LENGTH); \ + if (len > 0) { \ + libssh2_sha1_update(hash, value, len); \ + } else { \ + libssh2_sha1_update(hash, (version), 1); \ + libssh2_sha1_update(hash, session->session_id, session->session_id_len); \ + } \ + libssh2_sha1_final(hash, (value) + len); \ + len += SHA_DIGEST_LENGTH; \ + } \ } /* {{{ libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange * Diffie Hellman Key Exchange, Group Agnostic */ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *session, _libssh2_bn *g, _libssh2_bn *p, int group_order, - unsigned char packet_type_init, unsigned char packet_type_reply, - unsigned char *midhash, unsigned long midhash_len) + unsigned char packet_type_init, unsigned char packet_type_reply, + unsigned char *midhash, unsigned long midhash_len) { - unsigned char *e_packet = NULL, *s_packet = NULL, *tmp, h_sig_comp[SHA_DIGEST_LENGTH], c; - unsigned long e_packet_len, s_packet_len, tmp_len; - int ret = 0; - _libssh2_bn_ctx *ctx = _libssh2_bn_ctx_new(); - _libssh2_bn *x = _libssh2_bn_init(); /* Random from client */ - _libssh2_bn *e = _libssh2_bn_init(); /* g^x mod p */ - _libssh2_bn *f = _libssh2_bn_init(); /* g^(Random from server) mod p */ - _libssh2_bn *k = _libssh2_bn_init(); /* The shared secret: f^x mod p */ - unsigned char *s, *f_value, *k_value = NULL, *h_sig; - unsigned long f_value_len, k_value_len, h_sig_len; - libssh2_sha1_ctx exchange_hash; - int rc; + unsigned char *e_packet = NULL, *s_packet = NULL, *tmp, h_sig_comp[SHA_DIGEST_LENGTH], c; + unsigned long e_packet_len, s_packet_len, tmp_len; + int ret = 0; + _libssh2_bn_ctx *ctx = _libssh2_bn_ctx_new(); + _libssh2_bn *x = _libssh2_bn_init(); /* Random from client */ + _libssh2_bn *e = _libssh2_bn_init(); /* g^x mod p */ + _libssh2_bn *f = _libssh2_bn_init(); /* g^(Random from server) mod p */ + _libssh2_bn *k = _libssh2_bn_init(); /* The shared secret: f^x mod p */ + unsigned char *s, *f_value, *k_value = NULL, *h_sig; + unsigned long f_value_len, k_value_len, h_sig_len; + libssh2_sha1_ctx exchange_hash; + int rc; - /* Generate x and e */ - _libssh2_bn_rand(x, group_order, 0, -1); - _libssh2_bn_mod_exp(e, g, x, p, ctx); + /* Generate x and e */ + _libssh2_bn_rand(x, group_order, 0, -1); + _libssh2_bn_mod_exp(e, g, x, p, ctx); - /* Send KEX init */ - e_packet_len = _libssh2_bn_bytes(e) + 6; /* packet_type(1) + String Length(4) + leading 0(1) */ - if (_libssh2_bn_bits(e) % 8) { - /* Leading 00 not needed */ - e_packet_len--; - } - e_packet = LIBSSH2_ALLOC(session, e_packet_len); - if (!e_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory error", 0); - ret = -1; - goto clean_exit; - } - e_packet[0] = packet_type_init; - libssh2_htonu32(e_packet + 1, e_packet_len - 5); - if (_libssh2_bn_bits(e) % 8) { - _libssh2_bn_to_bin(e, e_packet + 5); - } else { - e_packet[5] = 0; - _libssh2_bn_to_bin(e, e_packet + 6); - } + /* Send KEX init */ + e_packet_len = _libssh2_bn_bytes(e) + 6; /* packet_type(1) + String Length(4) + leading 0(1) */ + if (_libssh2_bn_bits(e) % 8) { + /* Leading 00 not needed */ + e_packet_len--; + } + e_packet = LIBSSH2_ALLOC(session, e_packet_len); + if (!e_packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory error", 0); + ret = -1; + goto clean_exit; + } + e_packet[0] = packet_type_init; + libssh2_htonu32(e_packet + 1, e_packet_len - 5); + if (_libssh2_bn_bits(e) % 8) { + _libssh2_bn_to_bin(e, e_packet + 5); + } else { + e_packet[5] = 0; + _libssh2_bn_to_bin(e, e_packet + 6); + } - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending KEX packet %d", (int)packet_type_init); - rc = libssh2_packet_write(session, e_packet, e_packet_len); - if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send KEX init message", 0); - ret = -11; - goto clean_exit; - } + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending KEX packet %d", (int)packet_type_init); + rc = libssh2_packet_write(session, e_packet, e_packet_len); + if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send KEX init message", 0); + ret = -11; + goto clean_exit; + } - if (session->burn_optimistic_kexinit) { - /* The first KEX packet to come along will be the guess initially sent by the server - * That guess turned out to be wrong so we need to silently ignore it */ - int burn_type; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Waiting for badly guessed KEX packet (to be ignored)"); - burn_type = libssh2_packet_burn(session); - if (burn_type <= 0) { - /* Failed to receive a packet */ - ret = -1; - goto clean_exit; - } - session->burn_optimistic_kexinit = 0; + if (session->burn_optimistic_kexinit) { + /* The first KEX packet to come along will be the guess initially sent by the server + * That guess turned out to be wrong so we need to silently ignore it */ + int burn_type; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Waiting for badly guessed KEX packet (to be ignored)"); + burn_type = libssh2_packet_burn(session); + if (burn_type <= 0) { + /* Failed to receive a packet */ + ret = -1; + goto clean_exit; + } + session->burn_optimistic_kexinit = 0; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Burnt packet of type: %02x", (unsigned int)burn_type); - } + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Burnt packet of type: %02x", (unsigned int)burn_type); + } - /* Wait for KEX reply */ - rc = libssh2_packet_require(session, packet_type_reply, &s_packet, - &s_packet_len); - if (rc) { - libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, - "Timed out waiting for KEX reply", 0); - ret = -1; - goto clean_exit; - } + /* Wait for KEX reply */ + rc = libssh2_packet_require(session, packet_type_reply, &s_packet, + &s_packet_len); + if (rc) { + libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting for KEX reply", 0); + ret = -1; + goto clean_exit; + } - /* Parse KEXDH_REPLY */ - s = s_packet + 1; + /* Parse KEXDH_REPLY */ + s = s_packet + 1; - session->server_hostkey_len = libssh2_ntohu32(s); s += 4; - session->server_hostkey = LIBSSH2_ALLOC(session, session->server_hostkey_len); - if (!session->server_hostkey) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for a copy of the host key", 0); - ret = -1; - goto clean_exit; - } - memcpy(session->server_hostkey, s, session->server_hostkey_len); - s += session->server_hostkey_len; + session->server_hostkey_len = libssh2_ntohu32(s); s += 4; + session->server_hostkey = LIBSSH2_ALLOC(session, session->server_hostkey_len); + if (!session->server_hostkey) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for a copy of the host key", 0); + ret = -1; + goto clean_exit; + } + memcpy(session->server_hostkey, s, session->server_hostkey_len); + s += session->server_hostkey_len; #if LIBSSH2_MD5 { - libssh2_md5_ctx fingerprint_ctx; + libssh2_md5_ctx fingerprint_ctx; - libssh2_md5_init(&fingerprint_ctx); - libssh2_md5_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); - libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5); + libssh2_md5_init(&fingerprint_ctx); + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); + libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5); } #ifdef LIBSSH2DEBUG { - char fingerprint[50], *fprint = fingerprint; - int i; - for(i = 0; i < 16; i++, fprint += 3) { - snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); - } - *(--fprint) = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Server's MD5 Fingerprint: %s", fingerprint); + char fingerprint[50], *fprint = fingerprint; + int i; + for(i = 0; i < 16; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Server's MD5 Fingerprint: %s", fingerprint); } #endif /* LIBSSH2DEBUG */ #endif /* ! LIBSSH2_MD5 */ { - libssh2_sha1_ctx fingerprint_ctx; + libssh2_sha1_ctx fingerprint_ctx; - libssh2_sha1_init(&fingerprint_ctx); - libssh2_sha1_update (fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); - libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1); + libssh2_sha1_init(&fingerprint_ctx); + libssh2_sha1_update (fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); + libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1); } #ifdef LIBSSH2DEBUG { - char fingerprint[64], *fprint = fingerprint; - int i; - for(i = 0; i < 20; i++, fprint += 3) { - snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); - } - *(--fprint) = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Server's SHA1 Fingerprint: %s", fingerprint); + char fingerprint[64], *fprint = fingerprint; + int i; + for(i = 0; i < 20; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Server's SHA1 Fingerprint: %s", fingerprint); } #endif /* LIBSSH2DEBUG */ - if (session->hostkey->init(session, session->server_hostkey, session->server_hostkey_len, &session->server_hostkey_abstract)) { - libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unable to initialize hostkey importer", 0); - ret = -1; - goto clean_exit; - } + if (session->hostkey->init(session, session->server_hostkey, session->server_hostkey_len, &session->server_hostkey_abstract)) { + libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, "Unable to initialize hostkey importer", 0); + ret = -1; + goto clean_exit; + } - f_value_len = libssh2_ntohu32(s); s += 4; - f_value = s; s += f_value_len; - _libssh2_bn_from_bin(f, f_value_len, f_value); + f_value_len = libssh2_ntohu32(s); s += 4; + f_value = s; s += f_value_len; + _libssh2_bn_from_bin(f, f_value_len, f_value); - h_sig_len = libssh2_ntohu32(s); s += 4; - h_sig = s; + h_sig_len = libssh2_ntohu32(s); s += 4; + h_sig = s; - /* Compute the shared secret */ - _libssh2_bn_mod_exp(k, f, x, p, ctx); - k_value_len = _libssh2_bn_bytes(k) + 5; - if (_libssh2_bn_bits(k) % 8) { - /* don't need leading 00 */ - k_value_len--; - } - k_value = LIBSSH2_ALLOC(session, k_value_len); - if (!k_value) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate buffer for K", 0); - ret = -1; - goto clean_exit; - } - libssh2_htonu32(k_value, k_value_len - 4); - if (_libssh2_bn_bits(k) % 8) { - _libssh2_bn_to_bin(k, k_value + 4); - } else { - k_value[4] = 0; - _libssh2_bn_to_bin(k, k_value + 5); - } + /* Compute the shared secret */ + _libssh2_bn_mod_exp(k, f, x, p, ctx); + k_value_len = _libssh2_bn_bytes(k) + 5; + if (_libssh2_bn_bits(k) % 8) { + /* don't need leading 00 */ + k_value_len--; + } + k_value = LIBSSH2_ALLOC(session, k_value_len); + if (!k_value) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate buffer for K", 0); + ret = -1; + goto clean_exit; + } + libssh2_htonu32(k_value, k_value_len - 4); + if (_libssh2_bn_bits(k) % 8) { + _libssh2_bn_to_bin(k, k_value + 4); + } else { + k_value[4] = 0; + _libssh2_bn_to_bin(k, k_value + 5); + } - libssh2_sha1_init(&exchange_hash); - if (session->local.banner) { - libssh2_htonu32(h_sig_comp, - strlen((char *)session->local.banner) - 2); - libssh2_sha1_update(exchange_hash, h_sig_comp, 4); - libssh2_sha1_update(exchange_hash, (char *)session->local.banner, - strlen((char *)session->local.banner) - 2); - } else { - libssh2_htonu32(h_sig_comp, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); - libssh2_sha1_update(exchange_hash, h_sig_comp, 4); - libssh2_sha1_update(exchange_hash, LIBSSH2_SSH_DEFAULT_BANNER, - sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); - } + libssh2_sha1_init(&exchange_hash); + if (session->local.banner) { + libssh2_htonu32(h_sig_comp, + strlen((char *)session->local.banner) - 2); + libssh2_sha1_update(exchange_hash, h_sig_comp, 4); + libssh2_sha1_update(exchange_hash, (char *)session->local.banner, + strlen((char *)session->local.banner) - 2); + } else { + libssh2_htonu32(h_sig_comp, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + libssh2_sha1_update(exchange_hash, h_sig_comp, 4); + libssh2_sha1_update(exchange_hash, LIBSSH2_SSH_DEFAULT_BANNER, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + } - libssh2_htonu32(h_sig_comp, strlen((char *)session->remote.banner)); - libssh2_sha1_update(exchange_hash, h_sig_comp, 4); - libssh2_sha1_update(exchange_hash, session->remote.banner, - strlen((char *)session->remote.banner)); + libssh2_htonu32(h_sig_comp, strlen((char *)session->remote.banner)); + libssh2_sha1_update(exchange_hash, h_sig_comp, 4); + libssh2_sha1_update(exchange_hash, session->remote.banner, + strlen((char *)session->remote.banner)); - libssh2_htonu32(h_sig_comp, session->local.kexinit_len); - libssh2_sha1_update(exchange_hash, h_sig_comp, 4); - libssh2_sha1_update(exchange_hash, session->local.kexinit, session->local.kexinit_len); + libssh2_htonu32(h_sig_comp, session->local.kexinit_len); + libssh2_sha1_update(exchange_hash, h_sig_comp, 4); + libssh2_sha1_update(exchange_hash, session->local.kexinit, session->local.kexinit_len); - libssh2_htonu32(h_sig_comp, session->remote.kexinit_len); - libssh2_sha1_update(exchange_hash, h_sig_comp, 4); - libssh2_sha1_update(exchange_hash, session->remote.kexinit, session->remote.kexinit_len); + libssh2_htonu32(h_sig_comp, session->remote.kexinit_len); + libssh2_sha1_update(exchange_hash, h_sig_comp, 4); + libssh2_sha1_update(exchange_hash, session->remote.kexinit, session->remote.kexinit_len); - libssh2_htonu32(h_sig_comp, session->server_hostkey_len); - libssh2_sha1_update(exchange_hash, h_sig_comp, 4); - libssh2_sha1_update(exchange_hash, session->server_hostkey, session->server_hostkey_len); + libssh2_htonu32(h_sig_comp, session->server_hostkey_len); + libssh2_sha1_update(exchange_hash, h_sig_comp, 4); + libssh2_sha1_update(exchange_hash, session->server_hostkey, session->server_hostkey_len); - if (packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { - /* diffie-hellman-group-exchange hashes additional fields */ + if (packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { + /* diffie-hellman-group-exchange hashes additional fields */ #ifdef LIBSSH2_DH_GEX_NEW - libssh2_htonu32(h_sig_comp, LIBSSH2_DH_GEX_MINGROUP); - libssh2_htonu32(h_sig_comp + 4, LIBSSH2_DH_GEX_OPTGROUP); - libssh2_htonu32(h_sig_comp + 8, LIBSSH2_DH_GEX_MAXGROUP); - libssh2_sha1_update(exchange_hash, h_sig_comp, 12); + libssh2_htonu32(h_sig_comp, LIBSSH2_DH_GEX_MINGROUP); + libssh2_htonu32(h_sig_comp + 4, LIBSSH2_DH_GEX_OPTGROUP); + libssh2_htonu32(h_sig_comp + 8, LIBSSH2_DH_GEX_MAXGROUP); + libssh2_sha1_update(exchange_hash, h_sig_comp, 12); #else - libssh2_htonu32(h_sig_comp, LIBSSH2_DH_GEX_OPTGROUP); - libssh2_sha1_update(exchange_hash, h_sig_comp, 4); + libssh2_htonu32(h_sig_comp, LIBSSH2_DH_GEX_OPTGROUP); + libssh2_sha1_update(exchange_hash, h_sig_comp, 4); #endif - } + } - if (midhash) { - libssh2_sha1_update(exchange_hash, midhash, midhash_len); - } + if (midhash) { + libssh2_sha1_update(exchange_hash, midhash, midhash_len); + } - libssh2_sha1_update(exchange_hash, e_packet + 1, e_packet_len - 1); + libssh2_sha1_update(exchange_hash, e_packet + 1, e_packet_len - 1); - libssh2_htonu32(h_sig_comp, f_value_len); - libssh2_sha1_update(exchange_hash, h_sig_comp, 4); - libssh2_sha1_update(exchange_hash, f_value, f_value_len); + libssh2_htonu32(h_sig_comp, f_value_len); + libssh2_sha1_update(exchange_hash, h_sig_comp, 4); + libssh2_sha1_update(exchange_hash, f_value, f_value_len); - libssh2_sha1_update(exchange_hash, k_value, k_value_len); + libssh2_sha1_update(exchange_hash, k_value, k_value_len); - libssh2_sha1_final(exchange_hash, h_sig_comp); + libssh2_sha1_final(exchange_hash, h_sig_comp); - if (session->hostkey->sig_verify(session, h_sig, h_sig_len, h_sig_comp, 20, &session->server_hostkey_abstract)) { - libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, "Unable to verify hostkey signature", 0); - ret = -1; - goto clean_exit; - } + if (session->hostkey->sig_verify(session, h_sig, h_sig_len, h_sig_comp, 20, &session->server_hostkey_abstract)) { + libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, "Unable to verify hostkey signature", 0); + ret = -1; + goto clean_exit; + } - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending NEWKEYS message"); - c = SSH_MSG_NEWKEYS; - if (libssh2_packet_write(session, &c, 1)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send NEWKEYS message", 0); - ret = -1; - goto clean_exit; - } + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending NEWKEYS message"); + c = SSH_MSG_NEWKEYS; + if (libssh2_packet_write(session, &c, 1)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send NEWKEYS message", 0); + ret = -1; + goto clean_exit; + } - if (libssh2_packet_require(session, SSH_MSG_NEWKEYS, &tmp, &tmp_len)) { - libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timed out waiting for NEWKEYS", 0); - ret = -1; - goto clean_exit; - } - /* The first key exchange has been performed, switch to active crypt/comp/mac mode */ - session->state |= LIBSSH2_STATE_NEWKEYS; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Received NEWKEYS message"); + if (libssh2_packet_require(session, SSH_MSG_NEWKEYS, &tmp, &tmp_len)) { + libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timed out waiting for NEWKEYS", 0); + ret = -1; + goto clean_exit; + } + /* The first key exchange has been performed, switch to active crypt/comp/mac mode */ + session->state |= LIBSSH2_STATE_NEWKEYS; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Received NEWKEYS message"); - /* This will actually end up being just packet_type(1) for this packet type anyway */ - LIBSSH2_FREE(session, tmp); + /* This will actually end up being just packet_type(1) for this packet type anyway */ + LIBSSH2_FREE(session, tmp); - if (!session->session_id) { - session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH); - if (!session->session_id) { - ret = -1; - goto clean_exit; - } - memcpy(session->session_id, h_sig_comp, SHA_DIGEST_LENGTH); - session->session_id_len = SHA_DIGEST_LENGTH; - _libssh2_debug(session, LIBSSH2_DBG_KEX, - "session_id calculated"); - } - - /* Cleanup any existing cipher */ - if (session->local.crypt->dtor) { - session->local.crypt->dtor(session, &session->local.crypt_abstract); - } - - /* Calculate IV/Secret/Key for each direction */ - if (session->local.crypt->init) { - unsigned char *iv = NULL, *secret = NULL; - int free_iv = 0, free_secret = 0; - - LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, session->local.crypt->iv_len, "A"); - if (!iv) { - ret = -1; - goto clean_exit; - } - LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, session->local.crypt->secret_len, "C"); - if (!secret) { - LIBSSH2_FREE(session, iv); - ret = -1; - goto clean_exit; - } - if (session->local.crypt->init(session, session->local.crypt, iv, &free_iv, secret, &free_secret, 1, &session->local.crypt_abstract)) { - LIBSSH2_FREE(session, iv); - LIBSSH2_FREE(session, secret); - ret = -1; - goto clean_exit; - } - - if (free_iv) { - memset(iv, 0, session->local.crypt->iv_len); - LIBSSH2_FREE(session, iv); - } - - if (free_secret) { - memset(secret, 0, session->local.crypt->secret_len); - LIBSSH2_FREE(session, secret); - } - } + if (!session->session_id) { + session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH); + if (!session->session_id) { + ret = -1; + goto clean_exit; + } + memcpy(session->session_id, h_sig_comp, SHA_DIGEST_LENGTH); + session->session_id_len = SHA_DIGEST_LENGTH; _libssh2_debug(session, LIBSSH2_DBG_KEX, - "Client to Server IV and Key calculated"); + "session_id calculated"); + } - if (session->remote.crypt->dtor) { - /* Cleanup any existing cipher */ - session->remote.crypt->dtor(session, &session->remote.crypt_abstract); - } + /* Cleanup any existing cipher */ + if (session->local.crypt->dtor) { + session->local.crypt->dtor(session, &session->local.crypt_abstract); + } - if (session->remote.crypt->init) { - unsigned char *iv = NULL, *secret = NULL; - int free_iv = 0, free_secret = 0; + /* Calculate IV/Secret/Key for each direction */ + if (session->local.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; - LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, session->remote.crypt->iv_len, "B"); - if (!iv) { - ret = -1; - goto clean_exit; - } - LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, session->remote.crypt->secret_len, "D"); - if (!secret) { - LIBSSH2_FREE(session, iv); - ret = -1; - goto clean_exit; - } - if (session->remote.crypt->init(session, session->remote.crypt, iv, &free_iv, secret, &free_secret, 0, &session->remote.crypt_abstract)) { - LIBSSH2_FREE(session, iv); - LIBSSH2_FREE(session, secret); - ret = -1; - goto clean_exit; - } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, session->local.crypt->iv_len, "A"); + if (!iv) { + ret = -1; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, session->local.crypt->secret_len, "C"); + if (!secret) { + LIBSSH2_FREE(session, iv); + ret = -1; + goto clean_exit; + } + if (session->local.crypt->init(session, session->local.crypt, iv, &free_iv, secret, &free_secret, 1, &session->local.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = -1; + goto clean_exit; + } - if (free_iv) { - memset(iv, 0, session->remote.crypt->iv_len); - LIBSSH2_FREE(session, iv); - } + if (free_iv) { + memset(iv, 0, session->local.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } - if (free_secret) { - memset(secret, 0, session->remote.crypt->secret_len); - LIBSSH2_FREE(session, secret); - } - } - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Server to Client IV and Key calculated"); + if (free_secret) { + memset(secret, 0, session->local.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_DBG_KEX, + "Client to Server IV and Key calculated"); - if (session->local.mac->dtor) { - session->local.mac->dtor(session, &session->local.mac_abstract); - } + if (session->remote.crypt->dtor) { + /* Cleanup any existing cipher */ + session->remote.crypt->dtor(session, &session->remote.crypt_abstract); + } - if (session->local.mac->init) { - unsigned char *key = NULL; - int free_key = 0; + if (session->remote.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; - LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, session->local.mac->key_len, "E"); - if (!key) { - ret = -1; - goto clean_exit; - } - session->local.mac->init(session, key, &free_key, &session->local.mac_abstract); + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, session->remote.crypt->iv_len, "B"); + if (!iv) { + ret = -1; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, session->remote.crypt->secret_len, "D"); + if (!secret) { + LIBSSH2_FREE(session, iv); + ret = -1; + goto clean_exit; + } + if (session->remote.crypt->init(session, session->remote.crypt, iv, &free_iv, secret, &free_secret, 0, &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = -1; + goto clean_exit; + } - if (free_key) { - memset(key, 0, session->local.mac->key_len); - LIBSSH2_FREE(session, key); - } - } - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Client to Server HMAC Key calculated"); + if (free_iv) { + memset(iv, 0, session->remote.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } - if (session->remote.mac->dtor) { - session->remote.mac->dtor(session, &session->remote.mac_abstract); - } + if (free_secret) { + memset(secret, 0, session->remote.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Server to Client IV and Key calculated"); - if (session->remote.mac->init) { - unsigned char *key = NULL; - int free_key = 0; + if (session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } - LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, session->remote.mac->key_len, "F"); - if (!key) { - ret = -1; - goto clean_exit; - } - session->remote.mac->init(session, key, &free_key, &session->remote.mac_abstract); + if (session->local.mac->init) { + unsigned char *key = NULL; + int free_key = 0; - if (free_key) { - memset(key, 0, session->remote.mac->key_len); - LIBSSH2_FREE(session, key); - } - } - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Server to Client HMAC Key calculated"); + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, session->local.mac->key_len, "E"); + if (!key) { + ret = -1; + goto clean_exit; + } + session->local.mac->init(session, key, &free_key, &session->local.mac_abstract); + + if (free_key) { + memset(key, 0, session->local.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Client to Server HMAC Key calculated"); + + if (session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + if (session->remote.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, session->remote.mac->key_len, "F"); + if (!key) { + ret = -1; + goto clean_exit; + } + session->remote.mac->init(session, key, &free_key, &session->remote.mac_abstract); + + if (free_key) { + memset(key, 0, session->remote.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Server to Client HMAC Key calculated"); clean_exit: - _libssh2_bn_free(x); - _libssh2_bn_free(e); - _libssh2_bn_free(f); - _libssh2_bn_free(k); - _libssh2_bn_ctx_free(ctx); + _libssh2_bn_free(x); + _libssh2_bn_free(e); + _libssh2_bn_free(f); + _libssh2_bn_free(k); + _libssh2_bn_ctx_free(ctx); - if (e_packet) { - LIBSSH2_FREE(session, e_packet); - } + if (e_packet) { + LIBSSH2_FREE(session, e_packet); + } - if (s_packet) { - LIBSSH2_FREE(session, s_packet); - } + if (s_packet) { + LIBSSH2_FREE(session, s_packet); + } - if (k_value) { - LIBSSH2_FREE(session, k_value); - } + if (k_value) { + LIBSSH2_FREE(session, k_value); + } - if (session->server_hostkey) { - LIBSSH2_FREE(session, session->server_hostkey); - session->server_hostkey = NULL; - } + if (session->server_hostkey) { + LIBSSH2_FREE(session, session->server_hostkey); + session->server_hostkey = NULL; + } - return ret; + return ret; } /* }}} */ @@ -481,40 +481,40 @@ static int libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_S */ static int libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session) { - static const unsigned char p_value[128] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - /* g == 2 */ - _libssh2_bn *p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */ - _libssh2_bn *g = _libssh2_bn_init(); /* SSH2 defined value (2) */ - int ret; + static const unsigned char p_value[128] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + /* g == 2 */ + _libssh2_bn *p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */ + _libssh2_bn *g = _libssh2_bn_init(); /* SSH2 defined value (2) */ + int ret; - /* Initialize P and G */ - _libssh2_bn_set_word(g, 2); - _libssh2_bn_from_bin(p, 128, p_value); + /* Initialize P and G */ + _libssh2_bn_set_word(g, 2); + _libssh2_bn_from_bin(p, 128, p_value); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group1 Key Exchange"); + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group1 Key Exchange"); - ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, g, p, 128, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, NULL, 0); + ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, g, p, 128, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, NULL, 0); - _libssh2_bn_free(p); - _libssh2_bn_free(g); + _libssh2_bn_free(p); + _libssh2_bn_free(g); - return ret; + return ret; } /* }}} */ @@ -523,55 +523,55 @@ static int libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SE */ static int libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session) { - static const unsigned char p_value[256] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - /* g == 2 */ - _libssh2_bn *p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */ - _libssh2_bn *g = _libssh2_bn_init(); /* SSH2 defined value (2) */ - int ret; + static const unsigned char p_value[256] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + /* g == 2 */ + _libssh2_bn *p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */ + _libssh2_bn *g = _libssh2_bn_init(); /* SSH2 defined value (2) */ + int ret; - /* Initialize P and G */ - _libssh2_bn_set_word(g, 2); - _libssh2_bn_from_bin(p, 256, p_value); + /* Initialize P and G */ + _libssh2_bn_set_word(g, 2); + _libssh2_bn_from_bin(p, 256, p_value); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group14 Key Exchange"); - ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, g, p, 256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, NULL, 0); + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group14 Key Exchange"); + ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, g, p, 256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, NULL, 0); - _libssh2_bn_free(p); - _libssh2_bn_free(g); + _libssh2_bn_free(p); + _libssh2_bn_free(g); - return ret; + return ret; } /* }}} */ @@ -581,88 +581,88 @@ static int libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_S */ static int libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange(LIBSSH2_SESSION *session) { - unsigned char request[13], *s, *data; - unsigned long data_len, p_len, g_len, request_len; - _libssh2_bn *p = _libssh2_bn_init (); - _libssh2_bn *g = _libssh2_bn_init (); - int ret; + unsigned char request[13], *s, *data; + unsigned long data_len, p_len, g_len, request_len; + _libssh2_bn *p = _libssh2_bn_init (); + _libssh2_bn *g = _libssh2_bn_init (); + int ret; - /* Ask for a P and G pair */ + /* Ask for a P and G pair */ #ifdef LIBSSH2_DH_GEX_NEW - request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; - libssh2_htonu32(request + 1, LIBSSH2_DH_GEX_MINGROUP); - libssh2_htonu32(request + 5, LIBSSH2_DH_GEX_OPTGROUP); - libssh2_htonu32(request + 9, LIBSSH2_DH_GEX_MAXGROUP); - request_len = 13; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group-Exchange (New Method)"); + request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; + libssh2_htonu32(request + 1, LIBSSH2_DH_GEX_MINGROUP); + libssh2_htonu32(request + 5, LIBSSH2_DH_GEX_OPTGROUP); + libssh2_htonu32(request + 9, LIBSSH2_DH_GEX_MAXGROUP); + request_len = 13; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group-Exchange (New Method)"); #else - request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD; - libssh2_htonu32(request + 1, LIBSSH2_DH_GEX_OPTGROUP); - request_len = 5; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group-Exchange (Old Method)"); + request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD; + libssh2_htonu32(request + 1, LIBSSH2_DH_GEX_OPTGROUP); + request_len = 5; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group-Exchange (Old Method)"); #endif - if (libssh2_packet_write(session, request, request_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send Group Exchange Request", 0); - ret = -1; - goto dh_gex_clean_exit; - } + if (libssh2_packet_write(session, request, request_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send Group Exchange Request", 0); + ret = -1; + goto dh_gex_clean_exit; + } - if (libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, &data, &data_len)) { - libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timeout waiting for GEX_GROUP reply", 0); - ret = -1; - goto dh_gex_clean_exit; - } + if (libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, &data, &data_len)) { + libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timeout waiting for GEX_GROUP reply", 0); + ret = -1; + goto dh_gex_clean_exit; + } - s = data + 1; - p_len = libssh2_ntohu32(s); s += 4; - _libssh2_bn_from_bin(p, p_len, s); s += p_len; + s = data + 1; + p_len = libssh2_ntohu32(s); s += 4; + _libssh2_bn_from_bin(p, p_len, s); s += p_len; - g_len = libssh2_ntohu32(s); s += 4; - _libssh2_bn_from_bin(g, g_len, s); s += g_len; + g_len = libssh2_ntohu32(s); s += 4; + _libssh2_bn_from_bin(g, g_len, s); s += g_len; - ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, g, p, p_len, SSH_MSG_KEX_DH_GEX_INIT, SSH_MSG_KEX_DH_GEX_REPLY, data + 1, data_len - 1); + ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, g, p, p_len, SSH_MSG_KEX_DH_GEX_INIT, SSH_MSG_KEX_DH_GEX_REPLY, data + 1, data_len - 1); - LIBSSH2_FREE(session, data); + LIBSSH2_FREE(session, data); dh_gex_clean_exit: - _libssh2_bn_free(g); - _libssh2_bn_free(p); + _libssh2_bn_free(g); + _libssh2_bn_free(p); - return ret; + return ret; } /* }}} */ -#define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001 -#define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002 +#define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001 +#define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002 static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group1_sha1 = { - "diffie-hellman-group1-sha1", - libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange, - LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, + "diffie-hellman-group1-sha1", + libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group14_sha1 = { - "diffie-hellman-group14-sha1", - libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange, - LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, + "diffie-hellman-group14-sha1", + libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group_exchange_sha1 = { - "diffie-hellman-group-exchange-sha1", - libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange, - LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, + "diffie-hellman-group-exchange-sha1", + libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = { - &libssh2_kex_method_diffie_helman_group14_sha1, - &libssh2_kex_method_diffie_helman_group_exchange_sha1, - &libssh2_kex_method_diffie_helman_group1_sha1, - NULL + &libssh2_kex_method_diffie_helman_group14_sha1, + &libssh2_kex_method_diffie_helman_group_exchange_sha1, + &libssh2_kex_method_diffie_helman_group1_sha1, + NULL }; typedef struct _LIBSSH2_COMMON_METHOD { - const char *name; + const char *name; } LIBSSH2_COMMON_METHOD; /* {{{ libssh2_kex_method_strlen @@ -672,18 +672,18 @@ typedef struct _LIBSSH2_COMMON_METHOD { */ static size_t libssh2_kex_method_strlen(LIBSSH2_COMMON_METHOD **method) { - size_t len = 0; + size_t len = 0; - if (!method || !*method) { - return 0; - } + if (!method || !*method) { + return 0; + } - while (*method && (*method)->name) { - len += strlen((*method)->name) + 1; - method++; - } + while (*method && (*method)->name) { + len += strlen((*method)->name) + 1; + method++; + } - return len - 1; + return len - 1; } /* }}} */ @@ -692,169 +692,169 @@ static size_t libssh2_kex_method_strlen(LIBSSH2_COMMON_METHOD **method) */ static size_t libssh2_kex_method_list(unsigned char *buf, size_t list_strlen, LIBSSH2_COMMON_METHOD **method) { - libssh2_htonu32(buf, list_strlen); - buf += 4; + libssh2_htonu32(buf, list_strlen); + buf += 4; - if (!method || !*method) { - return 4; - } + if (!method || !*method) { + return 4; + } - while (*method && (*method)->name) { - int mlen = strlen((*method)->name); - memcpy(buf, (*method)->name, mlen); - buf += mlen; - *(buf++) = ','; - method++; - } + while (*method && (*method)->name) { + int mlen = strlen((*method)->name); + memcpy(buf, (*method)->name, mlen); + buf += mlen; + *(buf++) = ','; + method++; + } - return list_strlen + 4; + return list_strlen + 4; } /* }}} */ -#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) ((prefvar) ? strlen(prefvar) : libssh2_kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar))) -#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \ - if (prefvar) { \ - libssh2_htonu32((buf), (prefvarlen)); \ - buf += 4; \ - memcpy((buf), (prefvar), (prefvarlen)); \ - buf += (prefvarlen); \ - } else { \ - buf += libssh2_kex_method_list((buf), (prefvarlen), (LIBSSH2_COMMON_METHOD**)(defaultvar)); \ - } +#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) ((prefvar) ? strlen(prefvar) : libssh2_kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar))) +#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \ + if (prefvar) { \ + libssh2_htonu32((buf), (prefvarlen)); \ + buf += 4; \ + memcpy((buf), (prefvar), (prefvarlen)); \ + buf += (prefvarlen); \ + } else { \ + buf += libssh2_kex_method_list((buf), (prefvarlen), (LIBSSH2_COMMON_METHOD**)(defaultvar)); \ + } /* {{{ libssh2_kexinit * Send SSH_MSG_KEXINIT packet */ static int libssh2_kexinit(LIBSSH2_SESSION *session) { - size_t data_len = 62; /* packet_type(1) + cookie(16) + first_packet_follows(1) + reserved(4) + length longs(40) */ - size_t kex_len, hostkey_len = 0; - size_t crypt_cs_len, crypt_sc_len; - size_t comp_cs_len, comp_sc_len; - size_t mac_cs_len, mac_sc_len; - size_t lang_cs_len, lang_sc_len; - unsigned char *data, *s; + size_t data_len = 62; /* packet_type(1) + cookie(16) + first_packet_follows(1) + reserved(4) + length longs(40) */ + size_t kex_len, hostkey_len = 0; + size_t crypt_cs_len, crypt_sc_len; + size_t comp_cs_len, comp_sc_len; + size_t mac_cs_len, mac_sc_len; + size_t lang_cs_len, lang_sc_len; + unsigned char *data, *s; - kex_len = LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods); - hostkey_len = LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs, libssh2_hostkey_methods()); - crypt_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs, libssh2_crypt_methods()); - crypt_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs, libssh2_crypt_methods()); - mac_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs, libssh2_mac_methods()); - mac_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs, libssh2_mac_methods()); - comp_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs, libssh2_comp_methods()); - comp_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs, libssh2_comp_methods()); - lang_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL); - lang_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL); + kex_len = LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods); + hostkey_len = LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs, libssh2_hostkey_methods()); + crypt_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs, libssh2_crypt_methods()); + crypt_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs, libssh2_crypt_methods()); + mac_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs, libssh2_mac_methods()); + mac_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs, libssh2_mac_methods()); + comp_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs, libssh2_comp_methods()); + comp_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs, libssh2_comp_methods()); + lang_cs_len = LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL); + lang_sc_len = LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL); - data_len += kex_len + hostkey_len + \ - crypt_cs_len + crypt_sc_len + \ - comp_cs_len + comp_sc_len + \ - mac_cs_len + mac_sc_len + \ - lang_cs_len + lang_sc_len; + data_len += kex_len + hostkey_len + \ + crypt_cs_len + crypt_sc_len + \ + comp_cs_len + comp_sc_len + \ + mac_cs_len + mac_sc_len + \ + lang_cs_len + lang_sc_len; - s = data = LIBSSH2_ALLOC(session, data_len); - if (!data) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory", 0); - return -1; - } + s = data = LIBSSH2_ALLOC(session, data_len); + if (!data) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory", 0); + return -1; + } - *(s++) = SSH_MSG_KEXINIT; + *(s++) = SSH_MSG_KEXINIT; - libssh2_random(s, 16); - s += 16; + libssh2_random(s, 16); + s += 16; - /* Ennumerating through these lists twice is probably (certainly?) inefficient from a CPU standpoint, but it saves multiple malloc/realloc calls */ - LIBSSH2_METHOD_PREFS_STR(s, kex_len, session->kex_prefs, libssh2_kex_methods); - LIBSSH2_METHOD_PREFS_STR(s, hostkey_len, session->hostkey_prefs, libssh2_hostkey_methods()); - LIBSSH2_METHOD_PREFS_STR(s, crypt_cs_len, session->local.crypt_prefs, libssh2_crypt_methods()); - LIBSSH2_METHOD_PREFS_STR(s, crypt_sc_len, session->remote.crypt_prefs, libssh2_crypt_methods()); - LIBSSH2_METHOD_PREFS_STR(s, mac_cs_len, session->local.mac_prefs, libssh2_mac_methods()); - LIBSSH2_METHOD_PREFS_STR(s, mac_sc_len, session->remote.mac_prefs, libssh2_mac_methods()); - LIBSSH2_METHOD_PREFS_STR(s, comp_cs_len, session->local.comp_prefs, libssh2_comp_methods()); - LIBSSH2_METHOD_PREFS_STR(s, comp_sc_len, session->remote.comp_prefs, libssh2_comp_methods()); - LIBSSH2_METHOD_PREFS_STR(s, lang_cs_len, session->local.lang_prefs, NULL); - LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs, NULL); + /* Ennumerating through these lists twice is probably (certainly?) inefficient from a CPU standpoint, but it saves multiple malloc/realloc calls */ + LIBSSH2_METHOD_PREFS_STR(s, kex_len, session->kex_prefs, libssh2_kex_methods); + LIBSSH2_METHOD_PREFS_STR(s, hostkey_len, session->hostkey_prefs, libssh2_hostkey_methods()); + LIBSSH2_METHOD_PREFS_STR(s, crypt_cs_len, session->local.crypt_prefs, libssh2_crypt_methods()); + LIBSSH2_METHOD_PREFS_STR(s, crypt_sc_len, session->remote.crypt_prefs, libssh2_crypt_methods()); + LIBSSH2_METHOD_PREFS_STR(s, mac_cs_len, session->local.mac_prefs, libssh2_mac_methods()); + LIBSSH2_METHOD_PREFS_STR(s, mac_sc_len, session->remote.mac_prefs, libssh2_mac_methods()); + LIBSSH2_METHOD_PREFS_STR(s, comp_cs_len, session->local.comp_prefs, libssh2_comp_methods()); + LIBSSH2_METHOD_PREFS_STR(s, comp_sc_len, session->remote.comp_prefs, libssh2_comp_methods()); + LIBSSH2_METHOD_PREFS_STR(s, lang_cs_len, session->local.lang_prefs, NULL); + LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs, NULL); - /* No optimistic KEX packet follows */ - /* Deal with optimistic packets - * session->flags |= KEXINIT_OPTIMISTIC - * session->flags |= KEXINIT_METHODSMATCH - */ - *(s++) = 0; + /* No optimistic KEX packet follows */ + /* Deal with optimistic packets + * session->flags |= KEXINIT_OPTIMISTIC + * session->flags |= KEXINIT_METHODSMATCH + */ + *(s++) = 0; - /* Reserved == 0 */ - *(s++) = 0; - *(s++) = 0; - *(s++) = 0; - *(s++) = 0; + /* Reserved == 0 */ + *(s++) = 0; + *(s++) = 0; + *(s++) = 0; + *(s++) = 0; #ifdef LIBSSH2DEBUG { - /* Funnily enough, they'll all "appear" to be '\0' terminated */ - unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */ + /* Funnily enough, they'll all "appear" to be '\0' terminated */ + unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */ - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent KEX: %s", p); p += kex_len + 4; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent HOSTKEY: %s", p); p += hostkey_len + 4; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent CRYPT_CS: %s", p); p += crypt_cs_len + 4; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent CRYPT_SC: %s", p); p += crypt_sc_len + 4; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent MAC_CS: %s", p); p += mac_cs_len + 4; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent MAC_SC: %s", p); p += mac_sc_len + 4; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent COMP_CS: %s", p); p += comp_cs_len + 4; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent COMP_SC: %s", p); p += comp_sc_len + 4; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent LANG_CS: %s", p); p += lang_cs_len + 4; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent LANG_SC: %s", p); p += lang_sc_len + 4; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent KEX: %s", p); p += kex_len + 4; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent HOSTKEY: %s", p); p += hostkey_len + 4; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent CRYPT_CS: %s", p); p += crypt_cs_len + 4; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent CRYPT_SC: %s", p); p += crypt_sc_len + 4; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent MAC_CS: %s", p); p += mac_cs_len + 4; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent MAC_SC: %s", p); p += mac_sc_len + 4; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent COMP_CS: %s", p); p += comp_cs_len + 4; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent COMP_SC: %s", p); p += comp_sc_len + 4; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent LANG_CS: %s", p); p += lang_cs_len + 4; + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sent LANG_SC: %s", p); p += lang_sc_len + 4; } #endif /* LIBSSH2DEBUG */ - if (libssh2_packet_write(session, data, data_len)) { - LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send KEXINIT packet to remote host", 0); - return -1; - } + if (libssh2_packet_write(session, data, data_len)) { + LIBSSH2_FREE(session, data); + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send KEXINIT packet to remote host", 0); + return -1; + } - if (session->local.kexinit) { - LIBSSH2_FREE(session, session->local.kexinit); - } + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } - session->local.kexinit = data; - session->local.kexinit_len = data_len; + session->local.kexinit = data; + session->local.kexinit_len = data_len; - return 0; + return 0; } -/* }}} */ +/* }}} */ /* {{{ libssh2_kex_agree_instr * Kex specific variant of strstr() * Needle must be preceed by BOL or ',', and followed by ',' or EOL */ static unsigned char *libssh2_kex_agree_instr(unsigned char *haystack, unsigned long haystack_len, - const unsigned char *needle, unsigned long needle_len) + const unsigned char *needle, unsigned long needle_len) { - unsigned char *s; + unsigned char *s; - /* Haystack too short to bother trying */ - if (haystack_len < needle_len) { - return NULL; - } + /* Haystack too short to bother trying */ + if (haystack_len < needle_len) { + return NULL; + } - /* Needle at start of haystack */ - if ((strncmp(haystack, needle, needle_len) == 0) && - (needle_len == haystack_len || haystack[needle_len] == ',')) { - return haystack; - } + /* Needle at start of haystack */ + if ((strncmp(haystack, needle, needle_len) == 0) && + (needle_len == haystack_len || haystack[needle_len] == ',')) { + return haystack; + } - s = haystack; - /* Search until we run out of comas or we run out of haystack, - whichever comes first */ - while ((s = strchr(s, ',')) && ((haystack_len - (s - haystack)) > needle_len)) { - s++; - /* Needle at X position */ - if ((strncmp(s, needle, needle_len) == 0) && - (((s - haystack) + needle_len) == haystack_len || s[needle_len] == ',')) { - return s; - } - } + s = haystack; + /* Search until we run out of comas or we run out of haystack, + whichever comes first */ + while ((s = strchr(s, ',')) && ((haystack_len - (s - haystack)) > needle_len)) { + s++; + /* Needle at X position */ + if ((strncmp(s, needle, needle_len) == 0) && + (((s - haystack) + needle_len) == haystack_len || s[needle_len] == ',')) { + return s; + } + } - return NULL; + return NULL; } /* }}} */ @@ -862,14 +862,14 @@ static unsigned char *libssh2_kex_agree_instr(unsigned char *haystack, unsigned */ static const LIBSSH2_COMMON_METHOD *libssh2_get_method_by_name(const char *name, int name_len, const LIBSSH2_COMMON_METHOD **methodlist) { - while (*methodlist) { - if ((strlen((*methodlist)->name) == name_len) && - (strncmp((*methodlist)->name, name, name_len) == 0)) { - return *methodlist; - } - methodlist++; - } - return NULL; + while (*methodlist) { + if ((strlen((*methodlist)->name) == name_len) && + (strncmp((*methodlist)->name, name, name_len) == 0)) { + return *methodlist; + } + methodlist++; + } + return NULL; } /* }}} */ @@ -878,62 +878,62 @@ static const LIBSSH2_COMMON_METHOD *libssh2_get_method_by_name(const char *name, */ static int libssh2_kex_agree_hostkey(LIBSSH2_SESSION *session, unsigned long kex_flags, unsigned char *hostkey, unsigned long hostkey_len) { - const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods(); - unsigned char *s; + const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods(); + unsigned char *s; - if (session->hostkey_prefs) { - s = session->hostkey_prefs; + if (session->hostkey_prefs) { + s = session->hostkey_prefs; - while (s && *s) { - unsigned char *p = strchr(s, ','); - int method_len = (p ? (p - s) : strlen(s)); - if (libssh2_kex_agree_instr(hostkey, hostkey_len, s, method_len)) { - const LIBSSH2_HOSTKEY_METHOD *method = (const LIBSSH2_HOSTKEY_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)hostkeyp); + while (s && *s) { + unsigned char *p = strchr(s, ','); + int method_len = (p ? (p - s) : strlen(s)); + if (libssh2_kex_agree_instr(hostkey, hostkey_len, s, method_len)) { + const LIBSSH2_HOSTKEY_METHOD *method = (const LIBSSH2_HOSTKEY_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)hostkeyp); - if (!method) { - /* Invalid method -- Should never be reached */ - return -1; - } + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } - /* So far so good, but does it suit our purposes? (Encrypting vs Signing) */ - if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) || - (method->encrypt)) { - /* Either this hostkey can do encryption or this kex just doesn't require it */ - if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) == 0) || - (method->sig_verify)) { - /* Either this hostkey can do signing or this kex just doesn't require it */ - session->hostkey = method; - return 0; - } - } - } + /* So far so good, but does it suit our purposes? (Encrypting vs Signing) */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) || + (method->encrypt)) { + /* Either this hostkey can do encryption or this kex just doesn't require it */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) == 0) || + (method->sig_verify)) { + /* Either this hostkey can do signing or this kex just doesn't require it */ + session->hostkey = method; + return 0; + } + } + } - s = p ? p + 1 : NULL; - } - return -1; - } + s = p ? p + 1 : NULL; + } + return -1; + } - while (hostkeyp && (*hostkeyp)->name) { - s = libssh2_kex_agree_instr(hostkey, hostkey_len, - (unsigned char *)(*hostkeyp)->name, - strlen((*hostkeyp)->name)); - if (s) { - /* So far so good, but does it suit our purposes? (Encrypting vs Signing) */ - if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) || - ((*hostkeyp)->encrypt)) { - /* Either this hostkey can do encryption or this kex just doesn't require it */ - if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) == 0) || - ((*hostkeyp)->sig_verify)) { - /* Either this hostkey can do signing or this kex just doesn't require it */ - session->hostkey = *hostkeyp; - return 0; - } - } - } - hostkeyp++; - } + while (hostkeyp && (*hostkeyp)->name) { + s = libssh2_kex_agree_instr(hostkey, hostkey_len, + (unsigned char *)(*hostkeyp)->name, + strlen((*hostkeyp)->name)); + if (s) { + /* So far so good, but does it suit our purposes? (Encrypting vs Signing) */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) || + ((*hostkeyp)->encrypt)) { + /* Either this hostkey can do encryption or this kex just doesn't require it */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) == 0) || + ((*hostkeyp)->sig_verify)) { + /* Either this hostkey can do signing or this kex just doesn't require it */ + session->hostkey = *hostkeyp; + return 0; + } + } + } + hostkeyp++; + } - return -1; + return -1; } /* }}} */ @@ -941,67 +941,67 @@ static int libssh2_kex_agree_hostkey(LIBSSH2_SESSION *session, unsigned long kex * Agree on a Key Exchange method and a hostkey encoding type */ static int libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION *session, unsigned char *kex, unsigned long kex_len, - unsigned char *hostkey, unsigned long hostkey_len) + unsigned char *hostkey, unsigned long hostkey_len) { - const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods; - unsigned char *s; + const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods; + unsigned char *s; - if (session->kex_prefs) { - s = session->kex_prefs; + if (session->kex_prefs) { + s = session->kex_prefs; - while (s && *s) { - unsigned char *q, *p = strchr(s, ','); - int method_len = (p ? (p - s) : strlen(s)); - if ((q = libssh2_kex_agree_instr(kex, kex_len, s, method_len))) { - const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)kexp); + while (s && *s) { + unsigned char *q, *p = strchr(s, ','); + int method_len = (p ? (p - s) : strlen(s)); + if ((q = libssh2_kex_agree_instr(kex, kex_len, s, method_len))) { + const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)kexp); - if (!method) { - /* Invalid method -- Should never be reached */ - return -1; - } + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } - /* We've agreed on a key exchange method, - * Can we agree on a hostkey that works with this kex? - */ - if (libssh2_kex_agree_hostkey(session, method->flags, hostkey, hostkey_len) == 0) { - session->kex = method; - if (session->burn_optimistic_kexinit && (kex == q)) { - /* Server sent an optimistic packet, - * and client agrees with preference - * cancel burning the first KEX_INIT packet that comes in */ - session->burn_optimistic_kexinit = 0; - } - return 0; - } - } + /* We've agreed on a key exchange method, + * Can we agree on a hostkey that works with this kex? + */ + if (libssh2_kex_agree_hostkey(session, method->flags, hostkey, hostkey_len) == 0) { + session->kex = method; + if (session->burn_optimistic_kexinit && (kex == q)) { + /* Server sent an optimistic packet, + * and client agrees with preference + * cancel burning the first KEX_INIT packet that comes in */ + session->burn_optimistic_kexinit = 0; + } + return 0; + } + } - s = p ? p + 1 : NULL; - } - return -1; - } + s = p ? p + 1 : NULL; + } + return -1; + } - while (*kexp && (*kexp)->name) { - s = libssh2_kex_agree_instr(kex, kex_len, - (unsigned char *)(*kexp)->name, - strlen((*kexp)->name)); - if (s) { - /* We've agreed on a key exchange method, - * Can we agree on a hostkey that works with this kex? - */ - if (libssh2_kex_agree_hostkey(session, (*kexp)->flags, hostkey, hostkey_len) == 0) { - session->kex = *kexp; - if (session->burn_optimistic_kexinit && (kex == s)) { - /* Server sent an optimistic packet, - * and client agrees with preference - * cancel burning the first KEX_INIT packet that comes in */ - session->burn_optimistic_kexinit = 0; - } - return 0; - } - } - kexp++; - } - return -1; + while (*kexp && (*kexp)->name) { + s = libssh2_kex_agree_instr(kex, kex_len, + (unsigned char *)(*kexp)->name, + strlen((*kexp)->name)); + if (s) { + /* We've agreed on a key exchange method, + * Can we agree on a hostkey that works with this kex? + */ + if (libssh2_kex_agree_hostkey(session, (*kexp)->flags, hostkey, hostkey_len) == 0) { + session->kex = *kexp; + if (session->burn_optimistic_kexinit && (kex == s)) { + /* Server sent an optimistic packet, + * and client agrees with preference + * cancel burning the first KEX_INIT packet that comes in */ + session->burn_optimistic_kexinit = 0; + } + return 0; + } + } + kexp++; + } + return -1; } /* }}} */ @@ -1009,51 +1009,51 @@ static int libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION *session, unsigned char * Agree on a cipher algo */ static int libssh2_kex_agree_crypt(LIBSSH2_SESSION *session, - libssh2_endpoint_data *endpoint, - unsigned char *crypt, - unsigned long crypt_len) + libssh2_endpoint_data *endpoint, + unsigned char *crypt, + unsigned long crypt_len) { - const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods(); - unsigned char *s; - (void)session; + const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods(); + unsigned char *s; + (void)session; - if (endpoint->crypt_prefs) { - s = endpoint->crypt_prefs; + if (endpoint->crypt_prefs) { + s = endpoint->crypt_prefs; - while (s && *s) { - unsigned char *p = strchr(s, ','); - int method_len = (p ? (p - s) : strlen(s)); + while (s && *s) { + unsigned char *p = strchr(s, ','); + int method_len = (p ? (p - s) : strlen(s)); - if (libssh2_kex_agree_instr(crypt, crypt_len, s, method_len)) { - const LIBSSH2_CRYPT_METHOD *method = - (const LIBSSH2_CRYPT_METHOD*)libssh2_get_method_by_name((char *)s, method_len, (const LIBSSH2_COMMON_METHOD**)cryptp); + if (libssh2_kex_agree_instr(crypt, crypt_len, s, method_len)) { + const LIBSSH2_CRYPT_METHOD *method = + (const LIBSSH2_CRYPT_METHOD*)libssh2_get_method_by_name((char *)s, method_len, (const LIBSSH2_COMMON_METHOD**)cryptp); - if (!method) { - /* Invalid method -- Should never be reached */ - return -1; - } + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } - endpoint->crypt = method; - return 0; - } + endpoint->crypt = method; + return 0; + } - s = p ? p + 1 : NULL; - } - return -1; - } + s = p ? p + 1 : NULL; + } + return -1; + } - while (*cryptp && (*cryptp)->name) { - s = libssh2_kex_agree_instr(crypt, crypt_len, - (unsigned char *)(*cryptp)->name, - strlen((*cryptp)->name)); - if (s) { - endpoint->crypt = *cryptp; - return 0; - } - cryptp++; - } + while (*cryptp && (*cryptp)->name) { + s = libssh2_kex_agree_instr(crypt, crypt_len, + (unsigned char *)(*cryptp)->name, + strlen((*cryptp)->name)); + if (s) { + endpoint->crypt = *cryptp; + return 0; + } + cryptp++; + } - return -1; + return -1; } /* }}} */ @@ -1062,46 +1062,46 @@ static int libssh2_kex_agree_crypt(LIBSSH2_SESSION *session, */ static int libssh2_kex_agree_mac(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint, unsigned char *mac, unsigned long mac_len) { - const LIBSSH2_MAC_METHOD **macp = libssh2_mac_methods(); - unsigned char *s; - (void)session; + const LIBSSH2_MAC_METHOD **macp = libssh2_mac_methods(); + unsigned char *s; + (void)session; - if (endpoint->mac_prefs) { - s = endpoint->mac_prefs; + if (endpoint->mac_prefs) { + s = endpoint->mac_prefs; - while (s && *s) { - unsigned char *p = strchr(s, ','); - int method_len = (p ? (p - s) : strlen(s)); + while (s && *s) { + unsigned char *p = strchr(s, ','); + int method_len = (p ? (p - s) : strlen(s)); - if (libssh2_kex_agree_instr(mac, mac_len, s, method_len)) { - const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)macp); + if (libssh2_kex_agree_instr(mac, mac_len, s, method_len)) { + const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)macp); - if (!method) { - /* Invalid method -- Should never be reached */ - return -1; - } + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } - endpoint->mac = method; - return 0; - } + endpoint->mac = method; + return 0; + } - s = p ? p + 1 : NULL; - } - return -1; - } + s = p ? p + 1 : NULL; + } + return -1; + } - while (*macp && (*macp)->name) { - s = libssh2_kex_agree_instr(mac, mac_len, - (unsigned char *)(*macp)->name, - strlen((*macp)->name)); - if (s) { - endpoint->mac = *macp; - return 0; - } - macp++; - } + while (*macp && (*macp)->name) { + s = libssh2_kex_agree_instr(mac, mac_len, + (unsigned char *)(*macp)->name, + strlen((*macp)->name)); + if (s) { + endpoint->mac = *macp; + return 0; + } + macp++; + } - return -1; + return -1; } /* }}} */ @@ -1110,46 +1110,46 @@ static int libssh2_kex_agree_mac(LIBSSH2_SESSION *session, libssh2_endpoint_data */ static int libssh2_kex_agree_comp(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint, unsigned char *comp, unsigned long comp_len) { - const LIBSSH2_COMP_METHOD **compp = libssh2_comp_methods(); - unsigned char *s; - (void)session; + const LIBSSH2_COMP_METHOD **compp = libssh2_comp_methods(); + unsigned char *s; + (void)session; - if (endpoint->comp_prefs) { - s = endpoint->comp_prefs; + if (endpoint->comp_prefs) { + s = endpoint->comp_prefs; - while (s && *s) { - unsigned char *p = strchr(s, ','); - int method_len = (p ? (p - s) : strlen(s)); + while (s && *s) { + unsigned char *p = strchr(s, ','); + int method_len = (p ? (p - s) : strlen(s)); - if (libssh2_kex_agree_instr(comp, comp_len, s, method_len)) { - const LIBSSH2_COMP_METHOD *method = (const LIBSSH2_COMP_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)compp); + if (libssh2_kex_agree_instr(comp, comp_len, s, method_len)) { + const LIBSSH2_COMP_METHOD *method = (const LIBSSH2_COMP_METHOD*)libssh2_get_method_by_name(s, method_len, (const LIBSSH2_COMMON_METHOD**)compp); - if (!method) { - /* Invalid method -- Should never be reached */ - return -1; - } + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } - endpoint->comp = method; - return 0; - } + endpoint->comp = method; + return 0; + } - s = p ? p + 1 : NULL; - } - return -1; - } + s = p ? p + 1 : NULL; + } + return -1; + } - while (*compp && (*compp)->name) { - s = libssh2_kex_agree_instr(comp, comp_len, - (unsigned char *)(*compp)->name, - strlen((*compp)->name)); - if (s) { - endpoint->comp = *compp; - return 0; - } - compp++; - } + while (*compp && (*compp)->name) { + s = libssh2_kex_agree_instr(comp, comp_len, + (unsigned char *)(*compp)->name, + strlen((*compp)->name)); + if (s) { + endpoint->comp = *compp; + return 0; + } + compp++; + } - return -1; + return -1; } /* }}} */ @@ -1162,84 +1162,84 @@ static int libssh2_kex_agree_comp(LIBSSH2_SESSION *session, libssh2_endpoint_dat */ static int libssh2_kex_agree_methods(LIBSSH2_SESSION *session, unsigned char *data, unsigned data_len) { - unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc, *mac_cs, *mac_sc, *lang_cs, *lang_sc; - size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len, comp_sc_len, mac_cs_len, mac_sc_len, lang_cs_len, lang_sc_len; - unsigned char *s = data; + unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc, *mac_cs, *mac_sc, *lang_cs, *lang_sc; + size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len, comp_sc_len, mac_cs_len, mac_sc_len, lang_cs_len, lang_sc_len; + unsigned char *s = data; - /* Skip packet_type, we know it already */ - s++; + /* Skip packet_type, we know it already */ + s++; - /* Skip cookie, don't worry, it's preserved in the kexinit field */ - s += 16; + /* Skip cookie, don't worry, it's preserved in the kexinit field */ + s += 16; - /* Locate each string */ - kex_len = libssh2_ntohu32(s); kex = s + 4; s += 4 + kex_len; - hostkey_len = libssh2_ntohu32(s); hostkey = s + 4; s += 4 + hostkey_len; - crypt_cs_len = libssh2_ntohu32(s); crypt_cs = s + 4; s += 4 + crypt_cs_len; - crypt_sc_len = libssh2_ntohu32(s); crypt_sc = s + 4; s += 4 + crypt_sc_len; - mac_cs_len = libssh2_ntohu32(s); mac_cs = s + 4; s += 4 + mac_cs_len; - mac_sc_len = libssh2_ntohu32(s); mac_sc = s + 4; s += 4 + mac_sc_len; - comp_cs_len = libssh2_ntohu32(s); comp_cs = s + 4; s += 4 + comp_cs_len; - comp_sc_len = libssh2_ntohu32(s); comp_sc = s + 4; s += 4 + comp_sc_len; - lang_cs_len = libssh2_ntohu32(s); lang_cs = s + 4; s += 4 + lang_cs_len; - lang_sc_len = libssh2_ntohu32(s); lang_sc = s + 4; s += 4 + lang_sc_len; + /* Locate each string */ + kex_len = libssh2_ntohu32(s); kex = s + 4; s += 4 + kex_len; + hostkey_len = libssh2_ntohu32(s); hostkey = s + 4; s += 4 + hostkey_len; + crypt_cs_len = libssh2_ntohu32(s); crypt_cs = s + 4; s += 4 + crypt_cs_len; + crypt_sc_len = libssh2_ntohu32(s); crypt_sc = s + 4; s += 4 + crypt_sc_len; + mac_cs_len = libssh2_ntohu32(s); mac_cs = s + 4; s += 4 + mac_cs_len; + mac_sc_len = libssh2_ntohu32(s); mac_sc = s + 4; s += 4 + mac_sc_len; + comp_cs_len = libssh2_ntohu32(s); comp_cs = s + 4; s += 4 + comp_cs_len; + comp_sc_len = libssh2_ntohu32(s); comp_sc = s + 4; s += 4 + comp_sc_len; + lang_cs_len = libssh2_ntohu32(s); lang_cs = s + 4; s += 4 + lang_cs_len; + lang_sc_len = libssh2_ntohu32(s); lang_sc = s + 4; s += 4 + lang_sc_len; - /* If the server sent an optimistic packet, assume that it guessed wrong. - * If the guess is determined to be right (by libssh2_kex_agree_kex_hostkey) - * This flag will be reset to zero so that it's not ignored */ - session->burn_optimistic_kexinit = *(s++); - /* Next uint32 in packet is all zeros (reserved) */ + /* If the server sent an optimistic packet, assume that it guessed wrong. + * If the guess is determined to be right (by libssh2_kex_agree_kex_hostkey) + * This flag will be reset to zero so that it's not ignored */ + session->burn_optimistic_kexinit = *(s++); + /* Next uint32 in packet is all zeros (reserved) */ - if (data_len < (unsigned)(s - data)) - return -1; /* short packet */ + if (data_len < (unsigned)(s - data)) + return -1; /* short packet */ - if (libssh2_kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) { - return -1; - } + if (libssh2_kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) { + return -1; + } - if (libssh2_kex_agree_crypt(session, &session->local, crypt_cs, crypt_cs_len) || - libssh2_kex_agree_crypt(session, &session->remote, crypt_sc, crypt_sc_len)) { - return -1; - } + if (libssh2_kex_agree_crypt(session, &session->local, crypt_cs, crypt_cs_len) || + libssh2_kex_agree_crypt(session, &session->remote, crypt_sc, crypt_sc_len)) { + return -1; + } - if (libssh2_kex_agree_mac(session, &session->local, mac_cs, mac_cs_len) || - libssh2_kex_agree_mac(session, &session->remote, mac_sc, mac_sc_len)) { - return -1; - } + if (libssh2_kex_agree_mac(session, &session->local, mac_cs, mac_cs_len) || + libssh2_kex_agree_mac(session, &session->remote, mac_sc, mac_sc_len)) { + return -1; + } - if (libssh2_kex_agree_comp(session, &session->local, comp_cs, comp_cs_len) || - libssh2_kex_agree_comp(session, &session->remote, comp_sc, comp_sc_len)) { - return -1; - } + if (libssh2_kex_agree_comp(session, &session->local, comp_cs, comp_cs_len) || + libssh2_kex_agree_comp(session, &session->remote, comp_sc, comp_sc_len)) { + return -1; + } - if (libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len) || - libssh2_kex_agree_lang(session, &session->remote, lang_sc, lang_sc_len)) { - return -1; - } + if (libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len) || + libssh2_kex_agree_lang(session, &session->remote, lang_sc, lang_sc_len)) { + return -1; + } - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on KEX method: %s", session->kex->name); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on HOSTKEY method: %s", session->hostkey->name); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on CRYPT_CS method: %s", session->local.crypt->name); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on CRYPT_SC method: %s", session->remote.crypt->name); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on MAC_CS method: %s", session->local.mac->name); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on MAC_SC method: %s", session->remote.mac->name); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on COMP_CS method: %s", session->local.comp->name); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on COMP_SC method: %s", session->remote.comp->name); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on LANG_CS method:"); /* None yet */ - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on LANG_SC method:"); /* None yet */ + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on KEX method: %s", session->kex->name); + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on HOSTKEY method: %s", session->hostkey->name); + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on CRYPT_CS method: %s", session->local.crypt->name); + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on CRYPT_SC method: %s", session->remote.crypt->name); + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on MAC_CS method: %s", session->local.mac->name); + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on MAC_SC method: %s", session->remote.mac->name); + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on COMP_CS method: %s", session->local.comp->name); + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on COMP_SC method: %s", session->remote.comp->name); + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on LANG_CS method:"); /* None yet */ + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Agreed on LANG_SC method:"); /* None yet */ - /* Initialize compression layer */ - if (session->local.comp && session->local.comp->init && - session->local.comp->init(session, 1, &session->local.comp_abstract)) { - return -1; - } + /* Initialize compression layer */ + if (session->local.comp && session->local.comp->init && + session->local.comp->init(session, 1, &session->local.comp_abstract)) { + return -1; + } - if (session->remote.comp && session->remote.comp->init && - session->remote.comp->init(session, 0, &session->remote.comp_abstract)) { - return -1; - } + if (session->remote.comp && session->remote.comp->init && + session->remote.comp->init(session, 0, &session->remote.comp_abstract)) { + return -1; + } - return 0; + return 0; } /* }}} */ @@ -1249,74 +1249,74 @@ static int libssh2_kex_agree_methods(LIBSSH2_SESSION *session, unsigned char *da */ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange) /* session->flags |= SERVER */ { - unsigned char *data; - unsigned long data_len; - int rc = 0; + unsigned char *data; + unsigned long data_len; + int rc = 0; - /* Prevent loop in packet_add() */ - session->state |= LIBSSH2_STATE_EXCHANGING_KEYS; + /* Prevent loop in packet_add() */ + session->state |= LIBSSH2_STATE_EXCHANGING_KEYS; - if (reexchange) { - session->kex = NULL; + if (reexchange) { + session->kex = NULL; - if (session->hostkey && session->hostkey->dtor) { - session->hostkey->dtor(session, &session->server_hostkey_abstract); - } - session->hostkey = NULL; - } + if (session->hostkey && session->hostkey->dtor) { + session->hostkey->dtor(session, &session->server_hostkey_abstract); + } + session->hostkey = NULL; + } - if (!session->kex || !session->hostkey) { - /* Preserve in case of failure */ - unsigned char *oldlocal = session->local.kexinit; - unsigned long oldlocal_len = session->local.kexinit_len; + if (!session->kex || !session->hostkey) { + /* Preserve in case of failure */ + unsigned char *oldlocal = session->local.kexinit; + unsigned long oldlocal_len = session->local.kexinit_len; - session->local.kexinit = NULL; - if (libssh2_kexinit(session)) { - session->local.kexinit = oldlocal; - session->local.kexinit_len = oldlocal_len; - return -1; - } + session->local.kexinit = NULL; + if (libssh2_kexinit(session)) { + session->local.kexinit = oldlocal; + session->local.kexinit_len = oldlocal_len; + return -1; + } - if (libssh2_packet_require(session, SSH_MSG_KEXINIT, &data, &data_len)) { - if (session->local.kexinit) { - LIBSSH2_FREE(session, session->local.kexinit); - } - session->local.kexinit = oldlocal; - session->local.kexinit_len = oldlocal_len; - return -2; - } + if (libssh2_packet_require(session, SSH_MSG_KEXINIT, &data, &data_len)) { + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } + session->local.kexinit = oldlocal; + session->local.kexinit_len = oldlocal_len; + return -2; + } - if (session->remote.kexinit) { - LIBSSH2_FREE(session, session->remote.kexinit); - } - session->remote.kexinit = data; - session->remote.kexinit_len = data_len; + if (session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + } + session->remote.kexinit = data; + session->remote.kexinit_len = data_len; - if (libssh2_kex_agree_methods(session, data, data_len)) { - rc = -3; - } - } + if (libssh2_kex_agree_methods(session, data, data_len)) { + rc = -3; + } + } - if (rc == 0) { - if (session->kex->exchange_keys(session)) { - libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE, "Unrecoverable error exchanging keys", 0); - rc = -4; - } - } + if (rc == 0) { + if (session->kex->exchange_keys(session)) { + libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE, "Unrecoverable error exchanging keys", 0); + rc = -4; + } + } - /* Done with kexinit buffers */ - if (session->local.kexinit) { - LIBSSH2_FREE(session, session->local.kexinit); - session->local.kexinit = NULL; - } - if (session->remote.kexinit) { - LIBSSH2_FREE(session, session->remote.kexinit); - session->remote.kexinit = NULL; - } + /* Done with kexinit buffers */ + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + session->local.kexinit = NULL; + } + if (session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + session->remote.kexinit = NULL; + } - session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; - return rc; + return rc; } /* }}} */ @@ -1325,94 +1325,94 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange) /* session->f */ LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, const char *prefs) { - char **prefvar, *s, *newprefs; - int prefs_len = strlen(prefs); - const LIBSSH2_COMMON_METHOD **mlist; + char **prefvar, *s, *newprefs; + int prefs_len = strlen(prefs); + const LIBSSH2_COMMON_METHOD **mlist; - switch (method_type) { - case LIBSSH2_METHOD_KEX: - prefvar = &session->kex_prefs; - mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_kex_methods; - break; - case LIBSSH2_METHOD_HOSTKEY: - prefvar = &session->hostkey_prefs; - mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_hostkey_methods(); - break; - case LIBSSH2_METHOD_CRYPT_CS: - prefvar = &session->local.crypt_prefs; - mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_crypt_methods(); - break; - case LIBSSH2_METHOD_CRYPT_SC: - prefvar = &session->remote.crypt_prefs; - mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_crypt_methods(); - break; - case LIBSSH2_METHOD_MAC_CS: - prefvar = &session->local.mac_prefs; - mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_mac_methods(); - break; - case LIBSSH2_METHOD_MAC_SC: - prefvar = &session->remote.mac_prefs; - mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_mac_methods(); - break; - case LIBSSH2_METHOD_COMP_CS: - prefvar = &session->local.comp_prefs; - mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_comp_methods(); - break; - case LIBSSH2_METHOD_COMP_SC: - prefvar = &session->remote.comp_prefs; - mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_comp_methods(); - break; - case LIBSSH2_METHOD_LANG_CS: - prefvar = &session->local.lang_prefs; - mlist = NULL; - break; - case LIBSSH2_METHOD_LANG_SC: - prefvar = &session->remote.lang_prefs; - mlist = NULL; - break; - default: - libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type", 0); - return -1; - } + switch (method_type) { + case LIBSSH2_METHOD_KEX: + prefvar = &session->kex_prefs; + mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_kex_methods; + break; + case LIBSSH2_METHOD_HOSTKEY: + prefvar = &session->hostkey_prefs; + mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_hostkey_methods(); + break; + case LIBSSH2_METHOD_CRYPT_CS: + prefvar = &session->local.crypt_prefs; + mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_crypt_methods(); + break; + case LIBSSH2_METHOD_CRYPT_SC: + prefvar = &session->remote.crypt_prefs; + mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_crypt_methods(); + break; + case LIBSSH2_METHOD_MAC_CS: + prefvar = &session->local.mac_prefs; + mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_mac_methods(); + break; + case LIBSSH2_METHOD_MAC_SC: + prefvar = &session->remote.mac_prefs; + mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_mac_methods(); + break; + case LIBSSH2_METHOD_COMP_CS: + prefvar = &session->local.comp_prefs; + mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_comp_methods(); + break; + case LIBSSH2_METHOD_COMP_SC: + prefvar = &session->remote.comp_prefs; + mlist = (const LIBSSH2_COMMON_METHOD**)libssh2_comp_methods(); + break; + case LIBSSH2_METHOD_LANG_CS: + prefvar = &session->local.lang_prefs; + mlist = NULL; + break; + case LIBSSH2_METHOD_LANG_SC: + prefvar = &session->remote.lang_prefs; + mlist = NULL; + break; + default: + libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type", 0); + return -1; + } - s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1); - if (!newprefs) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocated space for method preferences", 0); - return -1; - } - memcpy(s, prefs, prefs_len + 1); + s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1); + if (!newprefs) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocated space for method preferences", 0); + return -1; + } + memcpy(s, prefs, prefs_len + 1); - while (s && *s) { - char *p = strchr(s, ','); - int method_len = p ? (p - s) : (int) strlen(s); + while (s && *s) { + char *p = strchr(s, ','); + int method_len = p ? (p - s) : (int) strlen(s); - if (!libssh2_get_method_by_name(s, method_len, mlist)) { - /* Strip out unsupported method */ - if (p) { - memcpy(s, p + 1, strlen(s) - method_len); - } else { - if (s > newprefs) { - *(--s) = '\0'; - } else { - *s = '\0'; - } - } - } + if (!libssh2_get_method_by_name(s, method_len, mlist)) { + /* Strip out unsupported method */ + if (p) { + memcpy(s, p + 1, strlen(s) - method_len); + } else { + if (s > newprefs) { + *(--s) = '\0'; + } else { + *s = '\0'; + } + } + } - s = p ? (p + 1) : NULL; - } + s = p ? (p + 1) : NULL; + } - if (strlen(newprefs) == 0) { - libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "The requested method(s) are not currently supported", 0); - LIBSSH2_FREE(session, newprefs); - return -1; - } + if (strlen(newprefs) == 0) { + libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "The requested method(s) are not currently supported", 0); + LIBSSH2_FREE(session, newprefs); + return -1; + } - if (*prefvar) { - LIBSSH2_FREE(session, *prefvar); - } - *prefvar = newprefs; + if (*prefvar) { + LIBSSH2_FREE(session, *prefvar); + } + *prefvar = newprefs; - return 0; + return 0; } /* }}} */ diff --git a/src/libgcrypt.c b/src/libgcrypt.c index c1304a2..623a1ad 100644 --- a/src/libgcrypt.c +++ b/src/libgcrypt.c @@ -39,529 +39,529 @@ #include int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, - const unsigned char *edata, - unsigned long elen, - const unsigned char *ndata, - unsigned long nlen, - const unsigned char *ddata, - unsigned long dlen, - const unsigned char *pdata, - unsigned long plen, - const unsigned char *qdata, - unsigned long qlen, - const unsigned char *e1data, - unsigned long e1len, - const unsigned char *e2data, - unsigned long e2len, - const unsigned char *coeffdata, - unsigned long coefflen) + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen) { - int rc; - (void)e1data; - (void)e1len; - (void)e2data; - (void)e2len; + int rc; + (void)e1data; + (void)e1len; + (void)e2data; + (void)e2len; - if (ddata) { - rc = gcry_sexp_build - (rsa, NULL, - "(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))", - nlen, ndata, elen, edata, dlen, ddata, plen, pdata, - qlen, qdata, coefflen, coeffdata); - } else { - rc = gcry_sexp_build (rsa, NULL, "(public-key(rsa(n%b)(e%b)))", - nlen, ndata, elen, edata); - } - if (rc) - { - *rsa = NULL; - return -1; - } + if (ddata) { + rc = gcry_sexp_build + (rsa, NULL, + "(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))", + nlen, ndata, elen, edata, dlen, ddata, plen, pdata, + qlen, qdata, coefflen, coeffdata); + } else { + rc = gcry_sexp_build (rsa, NULL, "(public-key(rsa(n%b)(e%b)))", + nlen, ndata, elen, edata); + } + if (rc) + { + *rsa = NULL; + return -1; + } - return 0; + return 0; } int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, - const unsigned char *sig, - unsigned long sig_len, - const unsigned char *m, - unsigned long m_len) + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len) { - unsigned char hash[SHA_DIGEST_LENGTH]; - gcry_sexp_t s_sig, s_hash; - int rc = -1; + unsigned char hash[SHA_DIGEST_LENGTH]; + gcry_sexp_t s_sig, s_hash; + int rc = -1; - libssh2_sha1(m, m_len, hash); + libssh2_sha1(m, m_len, hash); - rc = gcry_sexp_build (&s_hash, NULL, - "(data (flags pkcs1) (hash sha1 %b))", - SHA_DIGEST_LENGTH, hash); - if (rc != 0) { - return -1; - } + rc = gcry_sexp_build (&s_hash, NULL, + "(data (flags pkcs1) (hash sha1 %b))", + SHA_DIGEST_LENGTH, hash); + if (rc != 0) { + return -1; + } - rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s %b)))", - sig_len, sig); - if (rc != 0) { - gcry_sexp_release (s_hash); - return -1; - } + rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s %b)))", + sig_len, sig); + if (rc != 0) { + gcry_sexp_release (s_hash); + return -1; + } - rc = gcry_pk_verify (s_sig, s_hash, rsa); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); + rc = gcry_pk_verify (s_sig, s_hash, rsa); + gcry_sexp_release (s_sig); + gcry_sexp_release (s_hash); - return (rc == 0) ? 0 : -1; + return (rc == 0) ? 0 : -1; } int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx, - const unsigned char *p, - unsigned long p_len, - const unsigned char *q, - unsigned long q_len, - const unsigned char *g, - unsigned long g_len, - const unsigned char *y, - unsigned long y_len, - const unsigned char *x, - unsigned long x_len) + const unsigned char *p, + unsigned long p_len, + const unsigned char *q, + unsigned long q_len, + const unsigned char *g, + unsigned long g_len, + const unsigned char *y, + unsigned long y_len, + const unsigned char *x, + unsigned long x_len) { - int rc; + int rc; - if (x_len) { - rc = gcry_sexp_build - (dsactx, NULL, - "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))", - p_len, p, q_len, q, g_len, g, y_len, y, x_len, x); - } else { - rc = gcry_sexp_build (dsactx, NULL, - "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))", - p_len, p, q_len, q, g_len, g, y_len, y); - } + if (x_len) { + rc = gcry_sexp_build + (dsactx, NULL, + "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))", + p_len, p, q_len, q, g_len, g, y_len, y, x_len, x); + } else { + rc = gcry_sexp_build (dsactx, NULL, + "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))", + p_len, p, q_len, q, g_len, g, y_len, y); + } - if (rc) { - *dsactx = NULL; - return -1; - } + if (rc) { + *dsactx = NULL; + return -1; + } - return 0; + return 0; } int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, - LIBSSH2_SESSION *session, - FILE *fp, - unsigned const char *passphrase) + LIBSSH2_SESSION *session, + FILE *fp, + unsigned const char *passphrase) { - char *data, *save_data; - unsigned int datalen; - int ret; - char *n, *e, *d, *p, *q, *e1, *e2, *coeff; - unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen; + char *data, *save_data; + unsigned int datalen; + int ret; + char *n, *e, *d, *p, *q, *e1, *e2, *coeff; + unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen; - (void)passphrase; + (void)passphrase; - ret = _libssh2_pem_parse (session, - "-----BEGIN RSA PRIVATE KEY-----", - "-----END RSA PRIVATE KEY-----", - fp, &data, &datalen); - if (ret) { - return -1; - } + ret = _libssh2_pem_parse (session, + "-----BEGIN RSA PRIVATE KEY-----", + "-----END RSA PRIVATE KEY-----", + fp, &data, &datalen); + if (ret) { + return -1; + } - save_data = data; + save_data = data; - if (_libssh2_pem_decode_sequence (&data, &datalen)) { - ret = -1; - goto fail; - } + if (_libssh2_pem_decode_sequence (&data, &datalen)) { + ret = -1; + goto fail; + } /* First read Version field (should be 0). */ - ret = _libssh2_pem_decode_integer (&data, &datalen, &n, &nlen); - if (ret != 0 || (nlen != 1 && *n != '\0')) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &n, &nlen); + if (ret != 0 || (nlen != 1 && *n != '\0')) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &n, &nlen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &n, &nlen); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &e, &elen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &e, &elen); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &d, &dlen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &d, &dlen); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &q, &qlen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &q, &qlen); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &e1, &e1len); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &e1, &e1len); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &e2, &e2len); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &e2, &e2len); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &coeff, &coefflen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &coeff, &coefflen); + if (ret != 0) { + ret = -1; + goto fail; + } - if (_libssh2_rsa_new (rsa, e, elen, n, nlen, d, dlen, p, plen, - q, qlen, e1, e1len, e2, e2len, - coeff, coefflen)) { - ret = -1; - goto fail; - } + if (_libssh2_rsa_new (rsa, e, elen, n, nlen, d, dlen, p, plen, + q, qlen, e1, e1len, e2, e2len, + coeff, coefflen)) { + ret = -1; + goto fail; + } - ret = 0; + ret = 0; fail: - LIBSSH2_FREE (session, save_data); - return ret; + LIBSSH2_FREE (session, save_data); + return ret; } int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, - LIBSSH2_SESSION *session, - FILE *fp, - unsigned const char *passphrase) + LIBSSH2_SESSION *session, + FILE *fp, + unsigned const char *passphrase) { - char *data, *save_data; - unsigned int datalen; - int ret; - char *p, *q, *g, *y, *x; - unsigned int plen, qlen, glen, ylen, xlen; + char *data, *save_data; + unsigned int datalen; + int ret; + char *p, *q, *g, *y, *x; + unsigned int plen, qlen, glen, ylen, xlen; - (void)passphrase; + (void)passphrase; - ret = _libssh2_pem_parse (session, - "-----BEGIN DSA PRIVATE KEY-----", - "-----END DSA PRIVATE KEY-----", - fp, &data, &datalen); - if (ret) { - return -1; - } + ret = _libssh2_pem_parse (session, + "-----BEGIN DSA PRIVATE KEY-----", + "-----END DSA PRIVATE KEY-----", + fp, &data, &datalen); + if (ret) { + return -1; + } - save_data = data; + save_data = data; - if (_libssh2_pem_decode_sequence (&data, &datalen)) { - ret = -1; - goto fail; - } + if (_libssh2_pem_decode_sequence (&data, &datalen)) { + ret = -1; + goto fail; + } /* First read Version field (should be 0). */ - ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); - if (ret != 0 || (plen != 1 && *p != '\0')) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); + if (ret != 0 || (plen != 1 && *p != '\0')) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &p, &plen); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &q, &qlen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &q, &qlen); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &g, &glen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &g, &glen); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &y, &ylen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &y, &ylen); + if (ret != 0) { + ret = -1; + goto fail; + } - ret = _libssh2_pem_decode_integer (&data, &datalen, &x, &xlen); - if (ret != 0) { - ret = -1; - goto fail; - } + ret = _libssh2_pem_decode_integer (&data, &datalen, &x, &xlen); + if (ret != 0) { + ret = -1; + goto fail; + } - if (datalen != 0) { - ret = -1; - goto fail; - } + if (datalen != 0) { + ret = -1; + goto fail; + } - if (_libssh2_dsa_new (dsa, p, plen, q, qlen, - g, glen, y, ylen, x, xlen)) { - ret = -1; - goto fail; - } + if (_libssh2_dsa_new (dsa, p, plen, q, qlen, + g, glen, y, ylen, x, xlen)) { + ret = -1; + goto fail; + } - ret = 0; + ret = 0; fail: - LIBSSH2_FREE (session, save_data); - return ret; + LIBSSH2_FREE (session, save_data); + return ret; } int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, - libssh2_dsa_ctx *rsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char **signature, - unsigned long *signature_len) + libssh2_dsa_ctx *rsactx, + const unsigned char *hash, + unsigned long hash_len, + unsigned char **signature, + unsigned long *signature_len) { - gcry_sexp_t sig_sexp; - gcry_sexp_t data; - int rc; - const char *tmp; - size_t size; + gcry_sexp_t sig_sexp; + gcry_sexp_t data; + int rc; + const char *tmp; + size_t size; - if (hash_len != SHA_DIGEST_LENGTH) { - return -1; - } + if (hash_len != SHA_DIGEST_LENGTH) { + return -1; + } - if (gcry_sexp_build (&data, NULL, - "(data (flags pkcs1) (hash sha1 %b))", - hash_len, hash)) { - return -1; - } + if (gcry_sexp_build (&data, NULL, + "(data (flags pkcs1) (hash sha1 %b))", + hash_len, hash)) { + return -1; + } - rc = gcry_pk_sign (&sig_sexp, data, rsactx); + rc = gcry_pk_sign (&sig_sexp, data, rsactx); - gcry_sexp_release (data); + gcry_sexp_release (data); - if (rc != 0) { - return -1; - } + if (rc != 0) { + return -1; + } - data = gcry_sexp_find_token(sig_sexp, "s", 0); - if (!data) { - return -1; - } + data = gcry_sexp_find_token(sig_sexp, "s", 0); + if (!data) { + return -1; + } - tmp = gcry_sexp_nth_data(data, 1, &size); - if (!tmp) { - return -1; - } + tmp = gcry_sexp_nth_data(data, 1, &size); + if (!tmp) { + return -1; + } - if (tmp[0] == '\0') { - tmp++; - size--; - } + if (tmp[0] == '\0') { + tmp++; + size--; + } - *signature = LIBSSH2_ALLOC(session, size); - memcpy (*signature, tmp, size); - *signature_len = size; + *signature = LIBSSH2_ALLOC(session, size); + memcpy (*signature, tmp, size); + *signature_len = size; - return rc; + return rc; } int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char *sig) + const unsigned char *hash, + unsigned long hash_len, + unsigned char *sig) { - unsigned char zhash[SHA_DIGEST_LENGTH+1]; - gcry_sexp_t sig_sexp; - gcry_sexp_t data; - int ret; - const char *tmp; - size_t size; + unsigned char zhash[SHA_DIGEST_LENGTH+1]; + gcry_sexp_t sig_sexp; + gcry_sexp_t data; + int ret; + const char *tmp; + size_t size; - if (hash_len != SHA_DIGEST_LENGTH) { - return -1; - } + if (hash_len != SHA_DIGEST_LENGTH) { + return -1; + } - memcpy (zhash + 1, hash, hash_len); - zhash[0] = 0; + memcpy (zhash + 1, hash, hash_len); + zhash[0] = 0; - if (gcry_sexp_build (&data, NULL, "(data (value %b))", - hash_len + 1, zhash)) { - return -1; - } + if (gcry_sexp_build (&data, NULL, "(data (value %b))", + hash_len + 1, zhash)) { + return -1; + } - ret = gcry_pk_sign (&sig_sexp, data, dsactx); + ret = gcry_pk_sign (&sig_sexp, data, dsactx); - gcry_sexp_release (data); + gcry_sexp_release (data); - if (ret != 0) { - return -1; - } + if (ret != 0) { + return -1; + } /* Extract R. */ - data = gcry_sexp_find_token(sig_sexp, "r", 0); - if (!data) { - ret = -1; - goto out; - } + data = gcry_sexp_find_token(sig_sexp, "r", 0); + if (!data) { + ret = -1; + goto out; + } - tmp = gcry_sexp_nth_data(data, 1, &size); - if (!tmp) { - ret = -1; - goto out; - } + tmp = gcry_sexp_nth_data(data, 1, &size); + if (!tmp) { + ret = -1; + goto out; + } - if (tmp[0] == '\0') { - tmp++; - size--; - } + if (tmp[0] == '\0') { + tmp++; + size--; + } - if (size != 20) { - ret = -1; - goto out; - } + if (size != 20) { + ret = -1; + goto out; + } - memcpy (sig, tmp, 20); + memcpy (sig, tmp, 20); - gcry_sexp_release (data); + gcry_sexp_release (data); /* Extract S. */ - data = gcry_sexp_find_token(sig_sexp, "s",0); - if (!data) { - ret = -1; - goto out; - } + data = gcry_sexp_find_token(sig_sexp, "s",0); + if (!data) { + ret = -1; + goto out; + } - tmp = gcry_sexp_nth_data(data, 1, &size); - if (!tmp) { - ret = -1; - goto out; - } + tmp = gcry_sexp_nth_data(data, 1, &size); + if (!tmp) { + ret = -1; + goto out; + } - if (tmp[0] == '\0') { - tmp++; - size--; - } + if (tmp[0] == '\0') { + tmp++; + size--; + } - if (size != 20) { - ret = -1; - goto out; - } + if (size != 20) { + ret = -1; + goto out; + } - memcpy (sig + 20, tmp, 20); + memcpy (sig + 20, tmp, 20); - ret = 0; + ret = 0; out: - if (sig_sexp) { - gcry_sexp_release (sig_sexp); - } - if (data) { - gcry_sexp_release (data); - } - return ret; + if (sig_sexp) { + gcry_sexp_release (sig_sexp); + } + if (data) { + gcry_sexp_release (data); + } + return ret; } int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, - const unsigned char *sig, - const unsigned char *m, - unsigned long m_len) + const unsigned char *sig, + const unsigned char *m, + unsigned long m_len) { - unsigned char hash[SHA_DIGEST_LENGTH+1]; - gcry_sexp_t s_sig, s_hash; - int rc = -1; + unsigned char hash[SHA_DIGEST_LENGTH+1]; + gcry_sexp_t s_sig, s_hash; + int rc = -1; - libssh2_sha1(m, m_len, hash+1); - hash[0] = 0; + libssh2_sha1(m, m_len, hash+1); + hash[0] = 0; - if (gcry_sexp_build (&s_hash, NULL, "(data(flags raw)(value %b))", - SHA_DIGEST_LENGTH+1, hash)) { - return -1; - } + if (gcry_sexp_build (&s_hash, NULL, "(data(flags raw)(value %b))", + SHA_DIGEST_LENGTH+1, hash)) { + return -1; + } - if (gcry_sexp_build (&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))", - 20, sig, 20, sig + 20)) { - gcry_sexp_release (s_hash); - return -1; - } + if (gcry_sexp_build (&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))", + 20, sig, 20, sig + 20)) { + gcry_sexp_release (s_hash); + return -1; + } - rc = gcry_pk_verify (s_sig, s_hash, dsactx); - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); + rc = gcry_pk_verify (s_sig, s_hash, dsactx); + gcry_sexp_release (s_sig); + gcry_sexp_release (s_hash); - return (rc == 0) ? 0 : -1; + return (rc == 0) ? 0 : -1; } int _libssh2_cipher_init (_libssh2_cipher_ctx *h, - _libssh2_cipher_type(algo), - unsigned char *iv, - unsigned char *secret, - int encrypt) + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, + int encrypt) { - int mode = 0, ret; - int keylen = gcry_cipher_get_algo_keylen (algo); + int mode = 0, ret; + int keylen = gcry_cipher_get_algo_keylen (algo); - (void)encrypt; + (void)encrypt; - if (algo != GCRY_CIPHER_ARCFOUR) { - mode = GCRY_CIPHER_MODE_CBC; - } + if (algo != GCRY_CIPHER_ARCFOUR) { + mode = GCRY_CIPHER_MODE_CBC; + } - ret = gcry_cipher_open (h, algo, mode, 0); - if (ret) { - return -1; - } + ret = gcry_cipher_open (h, algo, mode, 0); + if (ret) { + return -1; + } - ret = gcry_cipher_setkey (*h, secret, keylen); - if (ret) { - gcry_cipher_close (*h); - return -1; - } + ret = gcry_cipher_setkey (*h, secret, keylen); + if (ret) { + gcry_cipher_close (*h); + return -1; + } - if (algo != GCRY_CIPHER_ARCFOUR) { - int blklen = gcry_cipher_get_algo_blklen (algo); - ret = gcry_cipher_setiv (*h, iv, blklen); - if (ret) { - gcry_cipher_close (*h); - return -1; - } - } + if (algo != GCRY_CIPHER_ARCFOUR) { + int blklen = gcry_cipher_get_algo_blklen (algo); + ret = gcry_cipher_setiv (*h, iv, blklen); + if (ret) { + gcry_cipher_close (*h); + return -1; + } + } - return 0; + return 0; } int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, - _libssh2_cipher_type(algo), - int encrypt, - unsigned char *block) + _libssh2_cipher_type(algo), + int encrypt, + unsigned char *block) { - size_t blklen = gcry_cipher_get_algo_blklen (algo); - int ret; - if (blklen == 1) { + size_t blklen = gcry_cipher_get_algo_blklen (algo); + int ret; + if (blklen == 1) { /* Hack for arcfour. */ - blklen = 8; - } + blklen = 8; + } - if (encrypt) { - ret = gcry_cipher_encrypt (*ctx, block, blklen, - block, blklen); - } else { - ret = gcry_cipher_decrypt (*ctx, block, blklen, - block, blklen); - } - return ret; + if (encrypt) { + ret = gcry_cipher_encrypt (*ctx, block, blklen, + block, blklen); + } else { + ret = gcry_cipher_decrypt (*ctx, block, blklen, + block, blklen); + } + return ret; } diff --git a/src/libgcrypt.h b/src/libgcrypt.h index 4853f95..8af17b8 100644 --- a/src/libgcrypt.h +++ b/src/libgcrypt.h @@ -53,7 +53,7 @@ #define MD5_DIGEST_LENGTH 16 #define SHA_DIGEST_LENGTH 20 -#define libssh2_random(buf, len) \ +#define libssh2_random(buf, len) \ (gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1) #define libssh2_sha1_ctx gcry_md_hd_t @@ -86,7 +86,7 @@ gcry_md_write (ctx, data, datalen) #define libssh2_hmac_final(ctx, data) \ memcpy (data, gcry_md_read (ctx, 0), \ - gcry_md_get_algo_dlen (gcry_md_get_algo (ctx))) + gcry_md_get_algo_dlen (gcry_md_get_algo (ctx))) #define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx); #define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM) @@ -94,65 +94,65 @@ #define libssh2_rsa_ctx struct gcry_sexp int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, - const unsigned char *edata, - unsigned long elen, - const unsigned char *ndata, - unsigned long nlen, - const unsigned char *ddata, - unsigned long dlen, - const unsigned char *pdata, - unsigned long plen, - const unsigned char *qdata, - unsigned long qlen, - const unsigned char *e1data, - unsigned long e1len, - const unsigned char *e2data, - unsigned long e2len, - const unsigned char *coeffdata, - unsigned long coefflen); + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen); int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, - LIBSSH2_SESSION *session, - FILE *fp, - unsigned const char *passphrase); + LIBSSH2_SESSION *session, + FILE *fp, + unsigned const char *passphrase); int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, - const unsigned char *sig, - unsigned long sig_len, - const unsigned char *m, - unsigned long m_len); + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len); int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, - libssh2_rsa_ctx *rsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char **signature, - unsigned long *signature_len); + libssh2_rsa_ctx *rsactx, + const unsigned char *hash, + unsigned long hash_len, + unsigned char **signature, + unsigned long *signature_len); #define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx) #define libssh2_dsa_ctx struct gcry_sexp int _libssh2_dsa_new(libssh2_dsa_ctx **dsa, - const unsigned char *pdata, - unsigned long plen, - const unsigned char *qdata, - unsigned long qlen, - const unsigned char *gdata, - unsigned long glen, - const unsigned char *ydata, - unsigned long ylen, - const unsigned char *x, - unsigned long x_len); + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *gdata, + unsigned long glen, + const unsigned char *ydata, + unsigned long ylen, + const unsigned char *x, + unsigned long x_len); int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, - LIBSSH2_SESSION *session, - FILE *fp, - unsigned const char *passphrase); + LIBSSH2_SESSION *session, + FILE *fp, + unsigned const char *passphrase); int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsa, - const unsigned char *sig, - const unsigned char *m, - unsigned long m_len); + const unsigned char *sig, + const unsigned char *m, + unsigned long m_len); int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char *sig); + const unsigned char *hash, + unsigned long hash_len, + unsigned char *sig); #define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx) @@ -168,15 +168,15 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, #define _libssh2_cipher_3des GCRY_CIPHER_3DES int _libssh2_cipher_init (_libssh2_cipher_ctx *h, - _libssh2_cipher_type(algo), - unsigned char *iv, - unsigned char *secret, - int encrypt); + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, + int encrypt); int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, - _libssh2_cipher_type(algo), - int encrypt, - unsigned char *block); + _libssh2_cipher_type(algo), + int encrypt, + unsigned char *block); #define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx)) diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h index b5bb669..9a5235d 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -90,325 +90,325 @@ */ #define MAX_SSH_PACKET_LEN 35000 -#define LIBSSH2_ALLOC(session, count) session->alloc((count), &(session)->abstract) -#define LIBSSH2_REALLOC(session, ptr, count) ((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : session->alloc((count), &(session)->abstract)) -#define LIBSSH2_FREE(session, ptr) session->free((ptr), &(session)->abstract) +#define LIBSSH2_ALLOC(session, count) session->alloc((count), &(session)->abstract) +#define LIBSSH2_REALLOC(session, ptr, count) ((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : session->alloc((count), &(session)->abstract)) +#define LIBSSH2_FREE(session, ptr) session->free((ptr), &(session)->abstract) -#define LIBSSH2_IGNORE(session, data, datalen) session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract) -#define LIBSSH2_DEBUG(session, always_display, message, message_len, language, language_len) \ - session->ssh_msg_disconnect((session), (always_display), (message), (message_len), (language), (language_len), &(session)->abstract) -#define LIBSSH2_DISCONNECT(session, reason, message, message_len, language, language_len) \ - session->ssh_msg_disconnect((session), (reason), (message), (message_len), (language), (language_len), &(session)->abstract) +#define LIBSSH2_IGNORE(session, data, datalen) session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract) +#define LIBSSH2_DEBUG(session, always_display, message, message_len, language, language_len) \ + session->ssh_msg_disconnect((session), (always_display), (message), (message_len), (language), (language_len), &(session)->abstract) +#define LIBSSH2_DISCONNECT(session, reason, message, message_len, language, language_len) \ + session->ssh_msg_disconnect((session), (reason), (message), (message_len), (language), (language_len), &(session)->abstract) -#define LIBSSH2_MACERROR(session, data, datalen) session->macerror((session), (data), (datalen), &(session)->abstract) -#define LIBSSH2_X11_OPEN(channel, shost, sport) channel->session->x11(((channel)->session), (channel), (shost), (sport), (&(channel)->session->abstract)) +#define LIBSSH2_MACERROR(session, data, datalen) session->macerror((session), (data), (datalen), &(session)->abstract) +#define LIBSSH2_X11_OPEN(channel, shost, sport) channel->session->x11(((channel)->session), (channel), (shost), (sport), (&(channel)->session->abstract)) -#define LIBSSH2_CHANNEL_CLOSE(session, channel) channel->close_cb((session), &(session)->abstract, (channel), &(channel)->abstract) +#define LIBSSH2_CHANNEL_CLOSE(session, channel) channel->close_cb((session), &(session)->abstract, (channel), &(channel)->abstract) -typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD; -typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD; -typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD; -typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD; -typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD; +typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD; +typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD; +typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD; +typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD; +typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD; -typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET; -typedef struct _LIBSSH2_PACKET_BRIGADE LIBSSH2_PACKET_BRIGADE; -typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE; +typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET; +typedef struct _LIBSSH2_PACKET_BRIGADE LIBSSH2_PACKET_BRIGADE; +typedef struct _LIBSSH2_CHANNEL_BRIGADE LIBSSH2_CHANNEL_BRIGADE; struct _LIBSSH2_PACKET { - unsigned char type; + unsigned char type; - /* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */ - unsigned char *data; - unsigned long data_len; + /* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */ + unsigned char *data; + unsigned long data_len; - /* Where to start reading data from, - * used for channel data that's been partially consumed */ - unsigned long data_head; + /* Where to start reading data from, + * used for channel data that's been partially consumed */ + unsigned long data_head; - /* Can the message be confirmed? */ - int mac; + /* Can the message be confirmed? */ + int mac; - LIBSSH2_PACKET_BRIGADE *brigade; + LIBSSH2_PACKET_BRIGADE *brigade; - LIBSSH2_PACKET *next, *prev; + LIBSSH2_PACKET *next, *prev; }; struct _LIBSSH2_PACKET_BRIGADE { - LIBSSH2_PACKET *head, *tail; + LIBSSH2_PACKET *head, *tail; }; typedef struct _libssh2_channel_data { - /* Identifier */ - unsigned long id; + /* Identifier */ + unsigned long id; - /* Limits and restrictions */ - unsigned long window_size_initial, window_size, packet_size; + /* Limits and restrictions */ + unsigned long window_size_initial, window_size, packet_size; - /* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */ - char close, eof, extended_data_ignore_mode; + /* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */ + char close, eof, extended_data_ignore_mode; } libssh2_channel_data; struct _LIBSSH2_CHANNEL { - unsigned char *channel_type; - unsigned channel_type_len; + unsigned char *channel_type; + unsigned channel_type_len; - int blocking; + int blocking; - /* channel's program exit status */ - int exit_status; + /* channel's program exit status */ + int exit_status; - libssh2_channel_data local, remote; - unsigned long adjust_queue; /* Amount of bytes to be refunded to receive window (but not yet sent) */ + libssh2_channel_data local, remote; + unsigned long adjust_queue; /* Amount of bytes to be refunded to receive window (but not yet sent) */ - LIBSSH2_SESSION *session; + LIBSSH2_SESSION *session; - LIBSSH2_CHANNEL *next, *prev; + LIBSSH2_CHANNEL *next, *prev; - void *abstract; - LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb)); + void *abstract; + LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb)); }; struct _LIBSSH2_CHANNEL_BRIGADE { - LIBSSH2_CHANNEL *head, *tail; + LIBSSH2_CHANNEL *head, *tail; }; struct _LIBSSH2_LISTENER { - LIBSSH2_SESSION *session; + LIBSSH2_SESSION *session; - char *host; - int port; + char *host; + int port; - LIBSSH2_CHANNEL *queue; - int queue_size; - int queue_maxsize; + LIBSSH2_CHANNEL *queue; + int queue_size; + int queue_maxsize; - LIBSSH2_LISTENER *prev, *next; + LIBSSH2_LISTENER *prev, *next; }; typedef struct _libssh2_endpoint_data { - unsigned char *banner; + unsigned char *banner; - unsigned char *kexinit; - unsigned long kexinit_len; + unsigned char *kexinit; + unsigned long kexinit_len; - const LIBSSH2_CRYPT_METHOD *crypt; - void *crypt_abstract; + const LIBSSH2_CRYPT_METHOD *crypt; + void *crypt_abstract; - const LIBSSH2_MAC_METHOD *mac; - unsigned long seqno; - void *mac_abstract; + const LIBSSH2_MAC_METHOD *mac; + unsigned long seqno; + void *mac_abstract; - const LIBSSH2_COMP_METHOD *comp; - void *comp_abstract; + const LIBSSH2_COMP_METHOD *comp; + void *comp_abstract; - /* Method Preferences -- NULL yields "load order" */ - char *crypt_prefs; - char *mac_prefs; - char *comp_prefs; - char *lang_prefs; + /* Method Preferences -- NULL yields "load order" */ + char *crypt_prefs; + char *mac_prefs; + char *comp_prefs; + char *lang_prefs; } libssh2_endpoint_data; #define PACKETBUFSIZE 4096 struct transportpacket { - /* ------------- for incoming data --------------- */ - unsigned char buf[PACKETBUFSIZE]; - unsigned char init[5]; /* first 5 bytes of the incoming data stream, - still encrypted */ - int writeidx; /* at what array index we do the next write into - the buffer */ - int readidx; /* at what array index we do the next read from - the buffer */ - int packet_length; /* the most recent packet_length as read from the - network data */ - int padding_length; /* the most recent padding_length as read from the - network data */ - int data_num; /* How much of the total package that has been read - so far. */ - int total_num; /* How much a total package is supposed to be, in - number of bytes. A full package is - packet_length + padding_length + 4 + - mac_length. */ - unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC() - area to which we write decrypted data */ - unsigned char *wptr; /* write pointer into the payload to where we - are currently writing decrypted data */ + /* ------------- for incoming data --------------- */ + unsigned char buf[PACKETBUFSIZE]; + unsigned char init[5]; /* first 5 bytes of the incoming data stream, + still encrypted */ + int writeidx; /* at what array index we do the next write into + the buffer */ + int readidx; /* at what array index we do the next read from + the buffer */ + int packet_length; /* the most recent packet_length as read from the + network data */ + int padding_length; /* the most recent padding_length as read from the + network data */ + int data_num; /* How much of the total package that has been read + so far. */ + int total_num; /* How much a total package is supposed to be, in + number of bytes. A full package is + packet_length + padding_length + 4 + + mac_length. */ + unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC() + area to which we write decrypted data */ + unsigned char *wptr; /* write pointer into the payload to where we + are currently writing decrypted data */ - /* ------------- for outgoing data --------------- */ - unsigned char *outbuf; /* pointer to a LIBSSH2_ALLOC() area for the - outgoing data */ - int ototal_num; /* size of outbuf in number of bytes */ - unsigned char *odata; /* original pointer to the data we stored in - outbuf */ - unsigned long olen; /* original size of the data we stored in - outbuf */ - unsigned long osent; /* number of bytes already sent */ + /* ------------- for outgoing data --------------- */ + unsigned char *outbuf; /* pointer to a LIBSSH2_ALLOC() area for the + outgoing data */ + int ototal_num; /* size of outbuf in number of bytes */ + unsigned char *odata; /* original pointer to the data we stored in + outbuf */ + unsigned long olen; /* original size of the data we stored in + outbuf */ + unsigned long osent; /* number of bytes already sent */ }; struct _LIBSSH2_SESSION { - /* Memory management callbacks */ - void *abstract; - LIBSSH2_ALLOC_FUNC((*alloc)); - LIBSSH2_REALLOC_FUNC((*realloc)); - LIBSSH2_FREE_FUNC((*free)); + /* Memory management callbacks */ + void *abstract; + LIBSSH2_ALLOC_FUNC((*alloc)); + LIBSSH2_REALLOC_FUNC((*realloc)); + LIBSSH2_FREE_FUNC((*free)); - /* Other callbacks */ - LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore)); - LIBSSH2_DEBUG_FUNC((*ssh_msg_debug)); - LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect)); - LIBSSH2_MACERROR_FUNC((*macerror)); - LIBSSH2_X11_OPEN_FUNC((*x11)); + /* Other callbacks */ + LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore)); + LIBSSH2_DEBUG_FUNC((*ssh_msg_debug)); + LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect)); + LIBSSH2_MACERROR_FUNC((*macerror)); + LIBSSH2_X11_OPEN_FUNC((*x11)); - /* Method preferences -- NULL yields "load order" */ - char *kex_prefs; - char *hostkey_prefs; + /* Method preferences -- NULL yields "load order" */ + char *kex_prefs; + char *hostkey_prefs; - int state; - int flags; + int state; + int flags; - /* Agreed Key Exchange Method */ - const LIBSSH2_KEX_METHOD *kex; - int burn_optimistic_kexinit:1; + /* Agreed Key Exchange Method */ + const LIBSSH2_KEX_METHOD *kex; + int burn_optimistic_kexinit:1; - unsigned char *session_id; - unsigned long session_id_len; + unsigned char *session_id; + unsigned long session_id_len; - /* Server's public key */ - const LIBSSH2_HOSTKEY_METHOD *hostkey; - void *server_hostkey_abstract; + /* Server's public key */ + const LIBSSH2_HOSTKEY_METHOD *hostkey; + void *server_hostkey_abstract; - /* Either set with libssh2_session_hostkey() (for server mode) - * Or read from server in (eg) KEXDH_INIT (for client mode) - */ - unsigned char *server_hostkey; - unsigned long server_hostkey_len; + /* Either set with libssh2_session_hostkey() (for server mode) + * Or read from server in (eg) KEXDH_INIT (for client mode) + */ + unsigned char *server_hostkey; + unsigned long server_hostkey_len; #if LIBSSH2_MD5 - unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH]; + unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH]; #endif /* ! LIBSSH2_MD5 */ - unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH]; + unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH]; - /* (remote as source of data -- packet_read ) */ - libssh2_endpoint_data remote; + /* (remote as source of data -- packet_read ) */ + libssh2_endpoint_data remote; - /* (local as source of data -- packet_write ) */ - libssh2_endpoint_data local; + /* (local as source of data -- packet_write ) */ + libssh2_endpoint_data local; - /* Inbound Data buffer -- Sometimes the packet that comes in isn't the packet we're ready for */ - LIBSSH2_PACKET_BRIGADE packets; + /* Inbound Data buffer -- Sometimes the packet that comes in isn't the packet we're ready for */ + LIBSSH2_PACKET_BRIGADE packets; - /* Active connection channels */ - LIBSSH2_CHANNEL_BRIGADE channels; - unsigned long next_channel; + /* Active connection channels */ + LIBSSH2_CHANNEL_BRIGADE channels; + unsigned long next_channel; - LIBSSH2_LISTENER *listeners; + LIBSSH2_LISTENER *listeners; - /* Actual I/O socket */ - int socket_fd; - int socket_block; - int socket_state; + /* Actual I/O socket */ + int socket_fd; + int socket_block; + int socket_state; - /* Error tracking */ - char *err_msg; - unsigned long err_msglen; - int err_should_free; - int err_code; + /* Error tracking */ + char *err_msg; + unsigned long err_msglen; + int err_should_free; + int err_code; - /* struct members for packet-level reading */ - struct transportpacket packet; + /* struct members for packet-level reading */ + struct transportpacket packet; #ifdef LIBSSH2DEBUG - int showmask; /* what debug/trace messages to display */ + int showmask; /* what debug/trace messages to display */ #endif }; /* session.state bits */ -#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001 -#define LIBSSH2_STATE_NEWKEYS 0x00000002 -#define LIBSSH2_STATE_AUTHENTICATED 0x00000004 +#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001 +#define LIBSSH2_STATE_NEWKEYS 0x00000002 +#define LIBSSH2_STATE_AUTHENTICATED 0x00000004 /* session.flag helpers */ #ifdef MSG_NOSIGNAL -#define LIBSSH2_SOCKET_SEND_FLAGS(session) (((session)->flags & LIBSSH2_FLAG_SIGPIPE) ? 0 : MSG_NOSIGNAL) -#define LIBSSH2_SOCKET_RECV_FLAGS(session) (((session)->flags & LIBSSH2_FLAG_SIGPIPE) ? 0 : MSG_NOSIGNAL) +#define LIBSSH2_SOCKET_SEND_FLAGS(session) (((session)->flags & LIBSSH2_FLAG_SIGPIPE) ? 0 : MSG_NOSIGNAL) +#define LIBSSH2_SOCKET_RECV_FLAGS(session) (((session)->flags & LIBSSH2_FLAG_SIGPIPE) ? 0 : MSG_NOSIGNAL) #else /* If MSG_NOSIGNAL isn't defined we're SOL on blocking SIGPIPE */ -#define LIBSSH2_SOCKET_SEND_FLAGS(session) 0 -#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0 +#define LIBSSH2_SOCKET_SEND_FLAGS(session) 0 +#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0 #endif /* libssh2 extensible ssh api, ultimately I'd like to allow loading additional methods via .so/.dll */ struct _LIBSSH2_KEX_METHOD { - const char *name; + const char *name; - /* Key exchange, populates session->* and returns 0 on success, non-0 on error */ - int (*exchange_keys)(LIBSSH2_SESSION *session); + /* Key exchange, populates session->* and returns 0 on success, non-0 on error */ + int (*exchange_keys)(LIBSSH2_SESSION *session); - long flags; + long flags; }; struct _LIBSSH2_HOSTKEY_METHOD { - const char *name; - unsigned long hash_len; + const char *name; + unsigned long hash_len; - int (*init)(LIBSSH2_SESSION *session, const unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract); - int (*initPEM)(LIBSSH2_SESSION *session, const char *privkeyfile, unsigned const char *passphrase, void **abstract); - int (*sig_verify)(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, void **abstract); - int (*signv)(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, unsigned long veccount, const struct iovec datavec[], void **abstract); - int (*encrypt)(LIBSSH2_SESSION *session, unsigned char **dst, unsigned long *dst_len, const unsigned char *src, unsigned long src_len, void **abstract); - int (*dtor)(LIBSSH2_SESSION *session, void **abstract); + int (*init)(LIBSSH2_SESSION *session, const unsigned char *hostkey_data, unsigned long hostkey_data_len, void **abstract); + int (*initPEM)(LIBSSH2_SESSION *session, const char *privkeyfile, unsigned const char *passphrase, void **abstract); + int (*sig_verify)(LIBSSH2_SESSION *session, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len, void **abstract); + int (*signv)(LIBSSH2_SESSION *session, unsigned char **signature, unsigned long *signature_len, unsigned long veccount, const struct iovec datavec[], void **abstract); + int (*encrypt)(LIBSSH2_SESSION *session, unsigned char **dst, unsigned long *dst_len, const unsigned char *src, unsigned long src_len, void **abstract); + int (*dtor)(LIBSSH2_SESSION *session, void **abstract); }; struct _LIBSSH2_CRYPT_METHOD { - const char *name; + const char *name; - int blocksize; + int blocksize; - /* iv and key sizes (-1 for variable length) */ - int iv_len; - int secret_len; + /* iv and key sizes (-1 for variable length) */ + int iv_len; + int secret_len; - long flags; + long flags; - int (*init)(LIBSSH2_SESSION *session, const LIBSSH2_CRYPT_METHOD *method, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract); - int (*crypt)(LIBSSH2_SESSION *session, unsigned char *block, void **abstract); - int (*dtor)(LIBSSH2_SESSION *session, void **abstract); + int (*init)(LIBSSH2_SESSION *session, const LIBSSH2_CRYPT_METHOD *method, unsigned char *iv, int *free_iv, unsigned char *secret, int *free_secret, int encrypt, void **abstract); + int (*crypt)(LIBSSH2_SESSION *session, unsigned char *block, void **abstract); + int (*dtor)(LIBSSH2_SESSION *session, void **abstract); - _libssh2_cipher_type(algo); + _libssh2_cipher_type(algo); }; struct _LIBSSH2_COMP_METHOD { - const char *name; + const char *name; - int (*init)(LIBSSH2_SESSION *session, int compress, void **abstract); - int (*comp)(LIBSSH2_SESSION *session, int compress, unsigned char **dest, unsigned long *dest_len, unsigned long payload_limit, int *free_dest, - const unsigned char *src, unsigned long src_len, void **abstract); - int (*dtor)(LIBSSH2_SESSION *session, int compress, void **abstract); + int (*init)(LIBSSH2_SESSION *session, int compress, void **abstract); + int (*comp)(LIBSSH2_SESSION *session, int compress, unsigned char **dest, unsigned long *dest_len, unsigned long payload_limit, int *free_dest, + const unsigned char *src, unsigned long src_len, void **abstract); + int (*dtor)(LIBSSH2_SESSION *session, int compress, void **abstract); }; struct _LIBSSH2_MAC_METHOD { - const char *name; + const char *name; - /* The length of a given MAC packet */ - int mac_len; + /* The length of a given MAC packet */ + int mac_len; - /* integrity key length */ - int key_len; + /* integrity key length */ + int key_len; - /* Message Authentication Code Hashing algo */ - int (*init)(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract); - int (*hash)(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, const unsigned char *packet, unsigned long packet_len, const unsigned char *addtl, unsigned long addtl_len, void **abstract); - int (*dtor)(LIBSSH2_SESSION *session, void **abstract); + /* Message Authentication Code Hashing algo */ + int (*init)(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract); + int (*hash)(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, const unsigned char *packet, unsigned long packet_len, const unsigned char *addtl, unsigned long addtl_len, void **abstract); + int (*dtor)(LIBSSH2_SESSION *session, void **abstract); }; -#define LIBSSH2_DBG_TRANS 1 -#define LIBSSH2_DBG_KEX 2 -#define LIBSSH2_DBG_AUTH 3 -#define LIBSSH2_DBG_CONN 4 -#define LIBSSH2_DBG_SCP 5 -#define LIBSSH2_DBG_SFTP 6 -#define LIBSSH2_DBG_ERROR 7 -#define LIBSSH2_DBG_PUBLICKEY 8 +#define LIBSSH2_DBG_TRANS 1 +#define LIBSSH2_DBG_KEX 2 +#define LIBSSH2_DBG_AUTH 3 +#define LIBSSH2_DBG_CONN 4 +#define LIBSSH2_DBG_SCP 5 +#define LIBSSH2_DBG_SFTP 6 +#define LIBSSH2_DBG_ERROR 7 +#define LIBSSH2_DBG_PUBLICKEY 8 #ifdef LIBSSH2DEBUG void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, ...); #else @@ -421,103 +421,103 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, . #else /* no gcc and not C99, do static and hopefully inline */ static inline void _libssh2_debug(LIBSSH2_SESSION *session, int context, - const char *format, ...) {} + const char *format, ...) {} #endif #endif #ifdef LIBSSH2DEBUG -#define libssh2_error(session, errcode, errmsg, should_free) \ +#define libssh2_error(session, errcode, errmsg, should_free) \ { \ - if (session->err_msg && session->err_should_free) { \ - LIBSSH2_FREE(session, session->err_msg); \ - } \ - session->err_msg = (char *)errmsg; \ - session->err_msglen = strlen(errmsg); \ - session->err_should_free = should_free; \ - session->err_code = errcode; \ - _libssh2_debug(session, LIBSSH2_DBG_ERROR, "%d - %s", session->err_code, session->err_msg); \ + if (session->err_msg && session->err_should_free) { \ + LIBSSH2_FREE(session, session->err_msg); \ + } \ + session->err_msg = (char *)errmsg; \ + session->err_msglen = strlen(errmsg); \ + session->err_should_free = should_free; \ + session->err_code = errcode; \ + _libssh2_debug(session, LIBSSH2_DBG_ERROR, "%d - %s", session->err_code, session->err_msg); \ } #else /* ! LIBSSH2DEBUG */ -#define libssh2_error(session, errcode, errmsg, should_free) \ +#define libssh2_error(session, errcode, errmsg, should_free) \ { \ - if (session->err_msg && session->err_should_free) { \ - LIBSSH2_FREE(session, session->err_msg); \ - } \ - session->err_msg = (char *)errmsg; \ - session->err_msglen = strlen(errmsg); \ - session->err_should_free = should_free; \ - session->err_code = errcode; \ + if (session->err_msg && session->err_should_free) { \ + LIBSSH2_FREE(session, session->err_msg); \ + } \ + session->err_msg = (char *)errmsg; \ + session->err_msglen = strlen(errmsg); \ + session->err_should_free = should_free; \ + session->err_code = errcode; \ } #endif /* LIBSSH2_DEBUG_ENABLED */ -#define LIBSSH2_SOCKET_UNKNOWN 1 -#define LIBSSH2_SOCKET_CONNECTED 0 -#define LIBSSH2_SOCKET_DISCONNECTED -1 +#define LIBSSH2_SOCKET_UNKNOWN 1 +#define LIBSSH2_SOCKET_CONNECTED 0 +#define LIBSSH2_SOCKET_DISCONNECTED -1 /* Initial packet state, prior to MAC check */ -#define LIBSSH2_MAC_UNCONFIRMED 1 +#define LIBSSH2_MAC_UNCONFIRMED 1 /* When MAC type is "none" (proto initiation phase) all packets are deemed "confirmed" */ -#define LIBSSH2_MAC_CONFIRMED 0 +#define LIBSSH2_MAC_CONFIRMED 0 /* Something very bad is going on */ -#define LIBSSH2_MAC_INVALID -1 +#define LIBSSH2_MAC_INVALID -1 /* SSH Packet Types -- Defined by internet draft */ /* Transport Layer */ -#define SSH_MSG_DISCONNECT 1 -#define SSH_MSG_IGNORE 2 -#define SSH_MSG_UNIMPLEMENTED 3 -#define SSH_MSG_DEBUG 4 -#define SSH_MSG_SERVICE_REQUEST 5 -#define SSH_MSG_SERVICE_ACCEPT 6 +#define SSH_MSG_DISCONNECT 1 +#define SSH_MSG_IGNORE 2 +#define SSH_MSG_UNIMPLEMENTED 3 +#define SSH_MSG_DEBUG 4 +#define SSH_MSG_SERVICE_REQUEST 5 +#define SSH_MSG_SERVICE_ACCEPT 6 -#define SSH_MSG_KEXINIT 20 -#define SSH_MSG_NEWKEYS 21 +#define SSH_MSG_KEXINIT 20 +#define SSH_MSG_NEWKEYS 21 /* diffie-hellman-group1-sha1 */ -#define SSH_MSG_KEXDH_INIT 30 -#define SSH_MSG_KEXDH_REPLY 31 +#define SSH_MSG_KEXDH_INIT 30 +#define SSH_MSG_KEXDH_REPLY 31 /* diffie-hellman-group-exchange-sha1 */ -#define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30 -#define SSH_MSG_KEX_DH_GEX_REQUEST 34 -#define SSH_MSG_KEX_DH_GEX_GROUP 31 -#define SSH_MSG_KEX_DH_GEX_INIT 32 -#define SSH_MSG_KEX_DH_GEX_REPLY 33 +#define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30 +#define SSH_MSG_KEX_DH_GEX_REQUEST 34 +#define SSH_MSG_KEX_DH_GEX_GROUP 31 +#define SSH_MSG_KEX_DH_GEX_INIT 32 +#define SSH_MSG_KEX_DH_GEX_REPLY 33 /* User Authentication */ -#define SSH_MSG_USERAUTH_REQUEST 50 -#define SSH_MSG_USERAUTH_FAILURE 51 -#define SSH_MSG_USERAUTH_SUCCESS 52 -#define SSH_MSG_USERAUTH_BANNER 53 +#define SSH_MSG_USERAUTH_REQUEST 50 +#define SSH_MSG_USERAUTH_FAILURE 51 +#define SSH_MSG_USERAUTH_SUCCESS 52 +#define SSH_MSG_USERAUTH_BANNER 53 /* "public key" method */ -#define SSH_MSG_USERAUTH_PK_OK 60 +#define SSH_MSG_USERAUTH_PK_OK 60 /* "password" method */ -#define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60 +#define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60 /* "keyboard-interactive" method */ -#define SSH_MSG_USERAUTH_INFO_REQUEST 60 -#define SSH_MSG_USERAUTH_INFO_RESPONSE 61 +#define SSH_MSG_USERAUTH_INFO_REQUEST 60 +#define SSH_MSG_USERAUTH_INFO_RESPONSE 61 /* Channels */ -#define SSH_MSG_GLOBAL_REQUEST 80 -#define SSH_MSG_REQUEST_SUCCESS 81 -#define SSH_MSG_REQUEST_FAILURE 82 +#define SSH_MSG_GLOBAL_REQUEST 80 +#define SSH_MSG_REQUEST_SUCCESS 81 +#define SSH_MSG_REQUEST_FAILURE 82 -#define SSH_MSG_CHANNEL_OPEN 90 -#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91 -#define SSH_MSG_CHANNEL_OPEN_FAILURE 92 -#define SSH_MSG_CHANNEL_WINDOW_ADJUST 93 -#define SSH_MSG_CHANNEL_DATA 94 -#define SSH_MSG_CHANNEL_EXTENDED_DATA 95 -#define SSH_MSG_CHANNEL_EOF 96 -#define SSH_MSG_CHANNEL_CLOSE 97 -#define SSH_MSG_CHANNEL_REQUEST 98 -#define SSH_MSG_CHANNEL_SUCCESS 99 -#define SSH_MSG_CHANNEL_FAILURE 100 +#define SSH_MSG_CHANNEL_OPEN 90 +#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91 +#define SSH_MSG_CHANNEL_OPEN_FAILURE 92 +#define SSH_MSG_CHANNEL_WINDOW_ADJUST 93 +#define SSH_MSG_CHANNEL_DATA 94 +#define SSH_MSG_CHANNEL_EXTENDED_DATA 95 +#define SSH_MSG_CHANNEL_EOF 96 +#define SSH_MSG_CHANNEL_CLOSE 97 +#define SSH_MSG_CHANNEL_REQUEST 98 +#define SSH_MSG_CHANNEL_SUCCESS 99 +#define SSH_MSG_CHANNEL_FAILURE 100 void libssh2_session_shutdown(LIBSSH2_SESSION *session); @@ -527,7 +527,7 @@ void libssh2_htonu32(unsigned char *buf, unsigned long val); void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t val); #define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when - waiting for more data to arrive */ + waiting for more data to arrive */ int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds); @@ -548,17 +548,17 @@ typedef int libssh2pack_t; libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session); int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket); -#define libssh2_packet_ask(session, packet_type, data, data_len, poll_socket) \ - libssh2_packet_ask_ex((session), (packet_type), (data), (data_len), 0, NULL, 0, (poll_socket)) +#define libssh2_packet_ask(session, packet_type, data, data_len, poll_socket) \ + libssh2_packet_ask_ex((session), (packet_type), (data), (data_len), 0, NULL, 0, (poll_socket)) int libssh2_packet_askv_ex(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len, int poll_socket); -#define libssh2_packet_askv(session, packet_types, data, data_len, poll_socket) \ - libssh2_packet_askv_ex((session), (packet_types), (data), (data_len), 0, NULL, 0, (poll_socket)) +#define libssh2_packet_askv(session, packet_types, data, data_len, poll_socket) \ + libssh2_packet_askv_ex((session), (packet_types), (data), (data_len), 0, NULL, 0, (poll_socket)) int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_type, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len); #define libssh2_packet_require(session, packet_type, data, data_len) \ libssh2_packet_require_ex((session), (packet_type), (data), (data_len), 0, NULL, 0) int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *packet_types, unsigned char **data, unsigned long *data_len, unsigned long match_ofs, const unsigned char *match_buf, unsigned long match_len); -#define libssh2_packet_requirev(session, packet_types, data, data_len) \ - libssh2_packet_requirev_ex((session), (packet_types), (data), (data_len), 0, NULL, 0) +#define libssh2_packet_requirev(session, packet_types, data, data_len) \ + libssh2_packet_requirev_ex((session), (packet_types), (data), (data_len), 0, NULL, 0) int libssh2_packet_burn(LIBSSH2_SESSION *session); int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len); int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, size_t datalen, int macstate); @@ -566,15 +566,15 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange); unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session); LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id); ssize_t _libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, - int stream_id, char *buf, size_t buflen); + int stream_id, char *buf, size_t buflen); #define _libssh2_channel_read(channel, buf, buflen) \ _libssh2_channel_read_ex((channel), 0, (buf), (buflen)) #undef libssh2_channel_read /* never use this internally */ #define libssh2_channel_read fix this code int _libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, - int stream_id, - const char *buf, size_t buflen); + int stream_id, + const char *buf, size_t buflen); #define _libssh2_channel_write(channel, buf, buflen) \ _libssh2_channel_write_ex((channel), 0, (buf), (buflen)) @@ -588,16 +588,16 @@ const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void); const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void); /* Language API doesn't exist yet. Just act like we've agreed on a language */ -#define libssh2_kex_agree_lang(session, endpoint, str, str_len) 0 +#define libssh2_kex_agree_lang(session, endpoint, str, str_len) 0 /* pem.c */ int _libssh2_pem_parse (LIBSSH2_SESSION *session, - const char *headerbegin, - const char *headerend, - FILE *fp, - char **data, unsigned int *datalen); + const char *headerbegin, + const char *headerend, + FILE *fp, + char **data, unsigned int *datalen); int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen); int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen, - unsigned char **i, unsigned int *ilen); + unsigned char **i, unsigned int *ilen); #endif /* LIBSSH2_H */ diff --git a/src/mac.c b/src/mac.c index 531d94b..cac69c1 100644 --- a/src/mac.c +++ b/src/mac.c @@ -42,21 +42,21 @@ * Minimalist MAC: No MAC */ static int libssh2_mac_none_MAC(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, - const unsigned char *packet, unsigned long packet_len, - const unsigned char *addtl, unsigned long addtl_len, void **abstract) + const unsigned char *packet, unsigned long packet_len, + const unsigned char *addtl, unsigned long addtl_len, void **abstract) { - return 0; + return 0; } /* }}} */ static LIBSSH2_MAC_METHOD libssh2_mac_method_none = { - "none", - 0, - 0, - NULL, - libssh2_mac_none_MAC, - NULL + "none", + 0, + 0, + NULL, + libssh2_mac_none_MAC, + NULL }; #endif /* LIBSSH2_MAC_NONE */ @@ -65,11 +65,11 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_none = { */ static int libssh2_mac_method_common_init(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract) { - *abstract = key; - *free_key = 0; - (void)session; + *abstract = key; + *free_key = 0; + (void)session; - return 0; + return 0; } /* }}} */ @@ -78,12 +78,12 @@ static int libssh2_mac_method_common_init(LIBSSH2_SESSION *session, unsigned cha */ static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstract) { - if (*abstract) { - LIBSSH2_FREE(session, *abstract); - } - *abstract = NULL; + if (*abstract) { + LIBSSH2_FREE(session, *abstract); + } + *abstract = NULL; - return 0; + return 0; } /* }}} */ @@ -91,120 +91,120 @@ static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstr * Calculate hash using full sha1 value */ static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, - const unsigned char *packet, unsigned long packet_len, - const unsigned char *addtl, unsigned long addtl_len, void **abstract) + const unsigned char *packet, unsigned long packet_len, + const unsigned char *addtl, unsigned long addtl_len, void **abstract) { - libssh2_hmac_ctx ctx; - unsigned char seqno_buf[4]; - (void)session; + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void)session; - libssh2_htonu32(seqno_buf, seqno); + libssh2_htonu32(seqno_buf, seqno); - libssh2_hmac_sha1_init(&ctx, *abstract, 20); - libssh2_hmac_update(ctx, seqno_buf, 4); - libssh2_hmac_update(ctx, packet, packet_len); - if (addtl && addtl_len) { - libssh2_hmac_update(ctx, addtl, addtl_len); - } - libssh2_hmac_final(ctx, buf); - libssh2_hmac_cleanup(&ctx); + libssh2_hmac_sha1_init(&ctx, *abstract, 20); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); - return 0; + return 0; } /* }}} */ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = { - "hmac-sha1", - 20, - 20, - libssh2_mac_method_common_init, - libssh2_mac_method_hmac_sha1_hash, - libssh2_mac_method_common_dtor, + "hmac-sha1", + 20, + 20, + libssh2_mac_method_common_init, + libssh2_mac_method_hmac_sha1_hash, + libssh2_mac_method_common_dtor, }; /* {{{ libssh2_mac_method_hmac_sha1_96_hash * Calculate hash using first 96 bits of sha1 value */ static int libssh2_mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, - const unsigned char *packet, unsigned long packet_len, - const unsigned char *addtl, unsigned long addtl_len, void **abstract) + const unsigned char *packet, unsigned long packet_len, + const unsigned char *addtl, unsigned long addtl_len, void **abstract) { - unsigned char temp[SHA_DIGEST_LENGTH]; + unsigned char temp[SHA_DIGEST_LENGTH]; - libssh2_mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract); - memcpy(buf, (char *)temp, 96 / 8); + libssh2_mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract); + memcpy(buf, (char *)temp, 96 / 8); - return 0; + return 0; } /* }}} */ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = { - "hmac-sha1-96", - 12, - 20, - libssh2_mac_method_common_init, - libssh2_mac_method_hmac_sha1_96_hash, - libssh2_mac_method_common_dtor, + "hmac-sha1-96", + 12, + 20, + libssh2_mac_method_common_init, + libssh2_mac_method_hmac_sha1_96_hash, + libssh2_mac_method_common_dtor, }; /* {{{ libssh2_mac_method_hmac_md5_hash * Calculate hash using full md5 value */ static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, - const unsigned char *packet, unsigned long packet_len, - const unsigned char *addtl, unsigned long addtl_len, void **abstract) + const unsigned char *packet, unsigned long packet_len, + const unsigned char *addtl, unsigned long addtl_len, void **abstract) { - libssh2_hmac_ctx ctx; - unsigned char seqno_buf[4]; - (void)session; + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void)session; - libssh2_htonu32(seqno_buf, seqno); + libssh2_htonu32(seqno_buf, seqno); - libssh2_hmac_md5_init(&ctx, *abstract, 16); - libssh2_hmac_update(ctx, seqno_buf, 4); - libssh2_hmac_update(ctx, packet, packet_len); - if (addtl && addtl_len) { - libssh2_hmac_update(ctx, addtl, addtl_len); - } - libssh2_hmac_final(ctx, buf); - libssh2_hmac_cleanup(&ctx); + libssh2_hmac_md5_init(&ctx, *abstract, 16); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); - return 0; + return 0; } /* }}} */ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = { - "hmac-md5", - 16, - 16, - libssh2_mac_method_common_init, - libssh2_mac_method_hmac_md5_hash, - libssh2_mac_method_common_dtor, + "hmac-md5", + 16, + 16, + libssh2_mac_method_common_init, + libssh2_mac_method_hmac_md5_hash, + libssh2_mac_method_common_dtor, }; /* {{{ libssh2_mac_method_hmac_md5_96_hash * Calculate hash using first 96 bits of md5 value */ static int libssh2_mac_method_hmac_md5_96_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, - const unsigned char *packet, unsigned long packet_len, - const unsigned char *addtl, unsigned long addtl_len, void **abstract) + const unsigned char *packet, unsigned long packet_len, + const unsigned char *addtl, unsigned long addtl_len, void **abstract) { - unsigned char temp[MD5_DIGEST_LENGTH]; + unsigned char temp[MD5_DIGEST_LENGTH]; - libssh2_mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract); - memcpy(buf, (char *)temp, 96 / 8); + libssh2_mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len, addtl, addtl_len, abstract); + memcpy(buf, (char *)temp, 96 / 8); - return 0; + return 0; } /* }}} */ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = { - "hmac-md5-96", - 12, - 16, - libssh2_mac_method_common_init, - libssh2_mac_method_hmac_md5_96_hash, - libssh2_mac_method_common_dtor, + "hmac-md5-96", + 12, + 16, + libssh2_mac_method_common_init, + libssh2_mac_method_hmac_md5_96_hash, + libssh2_mac_method_common_dtor, }; #if LIBSSH2_HMAC_RIPEMD @@ -212,63 +212,63 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = { * Calculate hash using ripemd160 value */ static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsigned char *buf, unsigned long seqno, - const unsigned char *packet, unsigned long packet_len, - const unsigned char *addtl, unsigned long addtl_len, void **abstract) + const unsigned char *packet, unsigned long packet_len, + const unsigned char *addtl, unsigned long addtl_len, void **abstract) { - libssh2_hmac_ctx ctx; - unsigned char seqno_buf[4]; - (void)session; + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void)session; - libssh2_htonu32(seqno_buf, seqno); + libssh2_htonu32(seqno_buf, seqno); - libssh2_hmac_ripemd160_init(&ctx, *abstract, 20); - libssh2_hmac_update(ctx, seqno_buf, 4); - libssh2_hmac_update(ctx, packet, packet_len); - if (addtl && addtl_len) { - libssh2_hmac_update(ctx, addtl, addtl_len); - } - libssh2_hmac_final(ctx, buf); - libssh2_hmac_cleanup(&ctx); + libssh2_hmac_ripemd160_init(&ctx, *abstract, 20); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); - return 0; + return 0; } /* }}} */ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = { - "hmac-ripemd160", - 20, - 20, - libssh2_mac_method_common_init, - libssh2_mac_method_hmac_ripemd160_hash, - libssh2_mac_method_common_dtor, + "hmac-ripemd160", + 20, + 20, + libssh2_mac_method_common_init, + libssh2_mac_method_hmac_ripemd160_hash, + libssh2_mac_method_common_dtor, }; static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160_openssh_com = { - "hmac-ripemd160@openssh.com", - 20, - 20, - libssh2_mac_method_common_init, - libssh2_mac_method_hmac_ripemd160_hash, - libssh2_mac_method_common_dtor, + "hmac-ripemd160@openssh.com", + 20, + 20, + libssh2_mac_method_common_init, + libssh2_mac_method_hmac_ripemd160_hash, + libssh2_mac_method_common_dtor, }; #endif /* LIBSSH2_HMAC_RIPEMD */ static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = { - &libssh2_mac_method_hmac_sha1, - &libssh2_mac_method_hmac_sha1_96, - &libssh2_mac_method_hmac_md5, - &libssh2_mac_method_hmac_md5_96, + &libssh2_mac_method_hmac_sha1, + &libssh2_mac_method_hmac_sha1_96, + &libssh2_mac_method_hmac_md5, + &libssh2_mac_method_hmac_md5_96, #ifdef LIBSSH2_HMAC_RIPEMD - &libssh2_mac_method_hmac_ripemd160, - &libssh2_mac_method_hmac_ripemd160_openssh_com, + &libssh2_mac_method_hmac_ripemd160, + &libssh2_mac_method_hmac_ripemd160_openssh_com, #endif /* LIBSSH2_HMAC_RIPEMD */ #ifdef LIBSSH2_MAC_NONE - &libssh2_mac_method_none, + &libssh2_mac_method_none, #endif /* LIBSSH2_MAC_NONE */ - NULL + NULL }; const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void) { - return _libssh2_mac_methods; + return _libssh2_mac_methods; } diff --git a/src/misc.c b/src/misc.c index b076d6c..e3c8b66 100644 --- a/src/misc.c +++ b/src/misc.c @@ -44,7 +44,7 @@ */ unsigned long libssh2_ntohu32(const unsigned char *buf) { - return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; } /* }}} */ @@ -54,12 +54,12 @@ unsigned long libssh2_ntohu32(const unsigned char *buf) */ libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf) { - unsigned long msl, lsl; + unsigned long msl, lsl; - msl = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; - lsl = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; + msl = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + lsl = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; - return ((msl * 65536) * 65536) + lsl; + return ((msl * 65536) * 65536) + lsl; } /* }}} */ @@ -67,10 +67,10 @@ libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf) */ void libssh2_htonu32(unsigned char *buf, unsigned long value) { - buf[0] = (value >> 24) & 0xFF; - buf[1] = (value >> 16) & 0xFF; - buf[2] = (value >> 8) & 0xFF; - buf[3] = value & 0xFF; + buf[0] = (value >> 24) & 0xFF; + buf[1] = (value >> 16) & 0xFF; + buf[2] = (value >> 8) & 0xFF; + buf[3] = value & 0xFF; } /* }}} */ @@ -78,17 +78,17 @@ void libssh2_htonu32(unsigned char *buf, unsigned long value) */ void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value) { - unsigned long msl = (value / 65536) / 65536; + unsigned long msl = (value / 65536) / 65536; - buf[0] = (msl >> 24) & 0xFF; - buf[1] = (msl >> 16) & 0xFF; - buf[2] = (msl >> 8) & 0xFF; - buf[3] = msl & 0xFF; + buf[0] = (msl >> 24) & 0xFF; + buf[1] = (msl >> 16) & 0xFF; + buf[2] = (msl >> 8) & 0xFF; + buf[3] = msl & 0xFF; - buf[4] = (value >> 24) & 0xFF; - buf[5] = (value >> 16) & 0xFF; - buf[6] = (value >> 8) & 0xFF; - buf[7] = value & 0xFF; + buf[4] = (value >> 24) & 0xFF; + buf[5] = (value >> 16) & 0xFF; + buf[6] = (value >> 8) & 0xFF; + buf[7] = value & 0xFF; } /* }}} */ @@ -130,97 +130,97 @@ static const short libssh2_base64_reverse_table[256] = { * Decode a base64 chunk and store it into a newly alloc'd buffer */ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, unsigned int *datalen, - const char *src, unsigned int src_len) + const char *src, unsigned int src_len) { - unsigned char *s, *d; - short v; - int i = 0, len = 0; + unsigned char *s, *d; + short v; + int i = 0, len = 0; - *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); - d = (unsigned char *)*data; - if (!d) { - return -1; - } + *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); + d = (unsigned char *)*data; + if (!d) { + return -1; + } - for(s = (unsigned char *)src; ((char*)s) < (src + src_len); s++) { - if ((v = libssh2_base64_reverse_table[*s]) < 0) continue; - switch (i % 4) { - case 0: - d[len] = v << 2; - break; - case 1: - d[len++] |= v >> 4; - d[len] = v << 4; - break; - case 2: - d[len++] |= v >> 2; - d[len] = v << 6; - break; - case 3: - d[len++] |= v; - break; - } - i++; - } - if ((i % 4) == 1) { - /* Invalid -- We have a byte which belongs exclusively to a partial octet */ - LIBSSH2_FREE(session, *data); - return -1; - } + for(s = (unsigned char *)src; ((char*)s) < (src + src_len); s++) { + if ((v = libssh2_base64_reverse_table[*s]) < 0) continue; + switch (i % 4) { + case 0: + d[len] = v << 2; + break; + case 1: + d[len++] |= v >> 4; + d[len] = v << 4; + break; + case 2: + d[len++] |= v >> 2; + d[len] = v << 6; + break; + case 3: + d[len++] |= v; + break; + } + i++; + } + if ((i % 4) == 1) { + /* Invalid -- We have a byte which belongs exclusively to a partial octet */ + LIBSSH2_FREE(session, *data); + return -1; + } - *datalen = len; - return 0; + *datalen = len; + return 0; } /* }}} */ #ifdef LIBSSH2DEBUG LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask) { - session->showmask = bitmask; - return 0; + session->showmask = bitmask; + return 0; } void _libssh2_debug(LIBSSH2_SESSION *session, int context, - const char *format, ...) + const char *format, ...) { - char buffer[1536]; - int len; - va_list vargs; - static const char * const contexts[9] = { - "Unknown", - "Transport", - "Key Exchange", - "Userauth", - "Connection", - "scp", - "SFTP Subsystem", - "Failure Event", - "Publickey Subsystem", - }; + char buffer[1536]; + int len; + va_list vargs; + static const char * const contexts[9] = { + "Unknown", + "Transport", + "Key Exchange", + "Userauth", + "Connection", + "scp", + "SFTP Subsystem", + "Failure Event", + "Publickey Subsystem", + }; - if (context < 1 || context > 8) { - context = 0; - } - if(!(session->showmask & (1< 8) { + context = 0; + } + if(!(session->showmask & (1<e = BN_new(); - BN_bin2bn(edata, elen, (*rsa)->e); + (*rsa)->e = BN_new(); + BN_bin2bn(edata, elen, (*rsa)->e); - (*rsa)->n = BN_new(); - BN_bin2bn(ndata, nlen, (*rsa)->n); + (*rsa)->n = BN_new(); + BN_bin2bn(ndata, nlen, (*rsa)->n); - if (ddata) - { - (*rsa)->d = BN_new(); - BN_bin2bn(ddata, dlen, (*rsa)->d); + if (ddata) { + (*rsa)->d = BN_new(); + BN_bin2bn(ddata, dlen, (*rsa)->d); - (*rsa)->p = BN_new(); - BN_bin2bn(pdata, plen, (*rsa)->p); + (*rsa)->p = BN_new(); + BN_bin2bn(pdata, plen, (*rsa)->p); - (*rsa)->q = BN_new(); - BN_bin2bn(qdata, qlen, (*rsa)->q); + (*rsa)->q = BN_new(); + BN_bin2bn(qdata, qlen, (*rsa)->q); - (*rsa)->dmp1 = BN_new(); - BN_bin2bn(e1data, e1len, (*rsa)->dmp1); + (*rsa)->dmp1 = BN_new(); + BN_bin2bn(e1data, e1len, (*rsa)->dmp1); - (*rsa)->dmq1 = BN_new(); - BN_bin2bn(e2data, e2len, (*rsa)->dmq1); + (*rsa)->dmq1 = BN_new(); + BN_bin2bn(e2data, e2len, (*rsa)->dmq1); - (*rsa)->iqmp = BN_new(); - BN_bin2bn(coeffdata, coefflen, (*rsa)->iqmp); - } - return 0; + (*rsa)->iqmp = BN_new(); + BN_bin2bn(coeffdata, coefflen, (*rsa)->iqmp); + } + return 0; } int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsactx, - const unsigned char *sig, - unsigned long sig_len, - const unsigned char *m, - unsigned long m_len) + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len) { - unsigned char hash[SHA_DIGEST_LENGTH]; - int ret; + unsigned char hash[SHA_DIGEST_LENGTH]; + int ret; - SHA1(m, m_len, hash); - ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH, - (unsigned char *)sig, sig_len, rsactx); - return (ret == 1) ? 0 : -1; + SHA1(m, m_len, hash); + ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH, + (unsigned char *)sig, sig_len, rsactx); + return (ret == 1) ? 0 : -1; } int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx, - const unsigned char *p, - unsigned long p_len, - const unsigned char *q, - unsigned long q_len, - const unsigned char *g, - unsigned long g_len, - const unsigned char *y, - unsigned long y_len, - const unsigned char *x, - unsigned long x_len) + const unsigned char *p, + unsigned long p_len, + const unsigned char *q, + unsigned long q_len, + const unsigned char *g, + unsigned long g_len, + const unsigned char *y, + unsigned long y_len, + const unsigned char *x, + unsigned long x_len) { - *dsactx = DSA_new(); + *dsactx = DSA_new(); - (*dsactx)->p = BN_new(); - BN_bin2bn(p, p_len, (*dsactx)->p); + (*dsactx)->p = BN_new(); + BN_bin2bn(p, p_len, (*dsactx)->p); - (*dsactx)->q = BN_new(); - BN_bin2bn(q, q_len, (*dsactx)->q); + (*dsactx)->q = BN_new(); + BN_bin2bn(q, q_len, (*dsactx)->q); - (*dsactx)->g = BN_new(); - BN_bin2bn(g, g_len, (*dsactx)->g); + (*dsactx)->g = BN_new(); + BN_bin2bn(g, g_len, (*dsactx)->g); - (*dsactx)->pub_key = BN_new(); - BN_bin2bn(y, y_len, (*dsactx)->pub_key); + (*dsactx)->pub_key = BN_new(); + BN_bin2bn(y, y_len, (*dsactx)->pub_key); - if (x_len) { - (*dsactx)->priv_key = BN_new(); - BN_bin2bn(x, x_len, (*dsactx)->priv_key); - } + if (x_len) { + (*dsactx)->priv_key = BN_new(); + BN_bin2bn(x, x_len, (*dsactx)->priv_key); + } - return 0; + return 0; } int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, - const unsigned char *sig, - const unsigned char *m, - unsigned long m_len) + const unsigned char *sig, + const unsigned char *m, + unsigned long m_len) { - unsigned char hash[SHA_DIGEST_LENGTH]; - DSA_SIG dsasig; - int ret; + unsigned char hash[SHA_DIGEST_LENGTH]; + DSA_SIG dsasig; + int ret; - dsasig.r = BN_new(); - BN_bin2bn(sig, 20, dsasig.r); - dsasig.s = BN_new(); - BN_bin2bn(sig + 20, 20, dsasig.s); + dsasig.r = BN_new(); + BN_bin2bn(sig, 20, dsasig.r); + dsasig.s = BN_new(); + BN_bin2bn(sig + 20, 20, dsasig.s); - libssh2_sha1(m, m_len, hash); - ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, &dsasig, dsactx); - BN_clear_free(dsasig.s); - BN_clear_free(dsasig.r); + libssh2_sha1(m, m_len, hash); + ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, &dsasig, dsactx); + BN_clear_free(dsasig.s); + BN_clear_free(dsasig.r); - return (ret == 1) ? 0 : -1; + return (ret == 1) ? 0 : -1; } int _libssh2_cipher_init (_libssh2_cipher_ctx *h, - _libssh2_cipher_type(algo), - unsigned char *iv, - unsigned char *secret, - int encrypt) + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, + int encrypt) { - EVP_CIPHER_CTX_init(h); - EVP_CipherInit(h, algo(), secret, iv, encrypt); - return 0; + EVP_CIPHER_CTX_init(h); + EVP_CipherInit(h, algo(), secret, iv, encrypt); + return 0; } int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, - _libssh2_cipher_type(algo), - int encrypt, - unsigned char *block) + _libssh2_cipher_type(algo), + int encrypt, + unsigned char *block) { - int blocksize = ctx->cipher->block_size; - unsigned char buf[EVP_MAX_BLOCK_LENGTH]; - int ret; - (void)algo; - (void)encrypt; + int blocksize = ctx->cipher->block_size; + unsigned char buf[EVP_MAX_BLOCK_LENGTH]; + int ret; + (void)algo; + (void)encrypt; - if (blocksize == 1) { + if (blocksize == 1) { /* Hack for arcfour. */ - blocksize = 8; - } - ret = EVP_Cipher(ctx, buf, block, blocksize); - if (ret == 1) { - memcpy(block, buf, blocksize); - } - return ret == 1 ? 0 : 1; + blocksize = 8; + } + ret = EVP_Cipher(ctx, buf, block, blocksize); + if (ret == 1) { + memcpy(block, buf, blocksize); + } + return ret == 1 ? 0 : 1; } /* TODO: Optionally call a passphrase callback specified by the @@ -201,119 +200,119 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, */ static int passphrase_cb(char *buf, int size, - int rwflag, char *passphrase) + int rwflag, char *passphrase) { - int passphrase_len = strlen(passphrase); - (void)rwflag; + int passphrase_len = strlen(passphrase); + (void)rwflag; - if (passphrase_len > (size - 1)) { - passphrase_len = size - 1; - } - memcpy(buf, passphrase, passphrase_len); - buf[passphrase_len] = '\0'; + if (passphrase_len > (size - 1)) { + passphrase_len = size - 1; + } + memcpy(buf, passphrase, passphrase_len); + buf[passphrase_len] = '\0'; - return passphrase_len; + return passphrase_len; } int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, - LIBSSH2_SESSION *session, - FILE *fp, - unsigned const char *passphrase) + LIBSSH2_SESSION *session, + FILE *fp, + unsigned const char *passphrase) { - (void)session; - if (!EVP_get_cipherbyname("des")) { + (void)session; + if (!EVP_get_cipherbyname("des")) { /* If this cipher isn't loaded it's a pretty good indication that none are. * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#( * Someone buy me an OpenSSL manual and I'll read up on it. */ - OpenSSL_add_all_ciphers(); - } - *rsa = PEM_read_RSAPrivateKey(fp, NULL, (void*)passphrase_cb, - (void*)passphrase); - if (!*rsa) { - return -1; - } - return 0; + OpenSSL_add_all_ciphers(); + } + *rsa = PEM_read_RSAPrivateKey(fp, NULL, (void*)passphrase_cb, + (void*)passphrase); + if (!*rsa) { + return -1; + } + return 0; } int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, - LIBSSH2_SESSION *session, - FILE *fp, - unsigned const char *passphrase) + LIBSSH2_SESSION *session, + FILE *fp, + unsigned const char *passphrase) { - (void)session; - if (!EVP_get_cipherbyname("des")) { + (void)session; + if (!EVP_get_cipherbyname("des")) { /* If this cipher isn't loaded it's a pretty good indication that none are. * I have *NO DOUBT* that there's a better way to deal with this ($#&%#$(%$#( * Someone buy me an OpenSSL manual and I'll read up on it. */ - OpenSSL_add_all_ciphers(); - } - *dsa = PEM_read_DSAPrivateKey(fp, NULL, (void*)passphrase_cb, - (void*)passphrase); - if (!*dsa) { - return -1; - } - return 0; + OpenSSL_add_all_ciphers(); + } + *dsa = PEM_read_DSAPrivateKey(fp, NULL, (void*)passphrase_cb, + (void*)passphrase); + if (!*dsa) { + return -1; + } + return 0; } int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, - libssh2_rsa_ctx *rsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char **signature, - unsigned long *signature_len) + libssh2_rsa_ctx *rsactx, + const unsigned char *hash, + unsigned long hash_len, + unsigned char **signature, + unsigned long *signature_len) { - int ret; - unsigned char *sig; - unsigned int sig_len; + int ret; + unsigned char *sig; + unsigned int sig_len; - sig_len = RSA_size(rsactx); - sig = LIBSSH2_ALLOC(session, sig_len); + sig_len = RSA_size(rsactx); + sig = LIBSSH2_ALLOC(session, sig_len); - if (!sig) { - return -1; - } + if (!sig) { + return -1; + } - ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx); + ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx); - if (!ret) { - LIBSSH2_FREE(session, sig); - return -1; - } + if (!ret) { + LIBSSH2_FREE(session, sig); + return -1; + } - *signature = sig; - *signature_len = sig_len; + *signature = sig; + *signature_len = sig_len; - return 0; + return 0; } int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char *signature) + const unsigned char *hash, + unsigned long hash_len, + unsigned char *signature) { - DSA_SIG *sig; - int r_len, s_len, rs_pad; - (void)hash_len; + DSA_SIG *sig; + int r_len, s_len, rs_pad; + (void)hash_len; - sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); - if (!sig) { - return -1; - } + sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); + if (!sig) { + return -1; + } - r_len = BN_num_bytes(sig->r); - s_len = BN_num_bytes(sig->s); - rs_pad = (2 * SHA_DIGEST_LENGTH) - (r_len + s_len); - if (rs_pad < 0) { - DSA_SIG_free(sig); - return -1; - } + r_len = BN_num_bytes(sig->r); + s_len = BN_num_bytes(sig->s); + rs_pad = (2 * SHA_DIGEST_LENGTH) - (r_len + s_len); + if (rs_pad < 0) { + DSA_SIG_free(sig); + return -1; + } - BN_bn2bin(sig->r, signature + rs_pad); - BN_bn2bin(sig->s, signature + rs_pad + r_len); + BN_bn2bin(sig->r, signature + rs_pad); + BN_bn2bin(sig->s, signature + rs_pad + r_len); - DSA_SIG_free(sig); + DSA_SIG_free(sig); - return 0; + return 0; } diff --git a/src/openssl.h b/src/openssl.h index de4aad0..7ed3446 100644 --- a/src/openssl.h +++ b/src/openssl.h @@ -100,7 +100,7 @@ # define LIBSSH2_3DES 1 #endif -#define libssh2_random(buf, len) \ +#define libssh2_random(buf, len) \ RAND_bytes ((buf), (len)) #define libssh2_sha1_ctx SHA_CTX @@ -132,65 +132,65 @@ #define libssh2_rsa_ctx RSA int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, - const unsigned char *edata, - unsigned long elen, - const unsigned char *ndata, - unsigned long nlen, - const unsigned char *ddata, - unsigned long dlen, - const unsigned char *pdata, - unsigned long plen, - const unsigned char *qdata, - unsigned long qlen, - const unsigned char *e1data, - unsigned long e1len, - const unsigned char *e2data, - unsigned long e2len, - const unsigned char *coeffdata, - unsigned long coefflen); + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen); int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, - LIBSSH2_SESSION *session, - FILE *fp, - unsigned const char *passphrase); + LIBSSH2_SESSION *session, + FILE *fp, + unsigned const char *passphrase); int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, - const unsigned char *sig, - unsigned long sig_len, - const unsigned char *m, - unsigned long m_len); + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len); int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, - libssh2_rsa_ctx *rsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char **signature, - unsigned long *signature_len); + libssh2_rsa_ctx *rsactx, + const unsigned char *hash, + unsigned long hash_len, + unsigned char **signature, + unsigned long *signature_len); #define _libssh2_rsa_free(rsactx) RSA_free(rsactx) #define libssh2_dsa_ctx DSA int _libssh2_dsa_new(libssh2_dsa_ctx **dsa, - const unsigned char *pdata, - unsigned long plen, - const unsigned char *qdata, - unsigned long qlen, - const unsigned char *gdata, - unsigned long glen, - const unsigned char *ydata, - unsigned long ylen, - const unsigned char *x, - unsigned long x_len); + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *gdata, + unsigned long glen, + const unsigned char *ydata, + unsigned long ylen, + const unsigned char *x, + unsigned long x_len); int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, - LIBSSH2_SESSION *session, - FILE *fp, - unsigned const char *passphrase); + LIBSSH2_SESSION *session, + FILE *fp, + unsigned const char *passphrase); int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, - const unsigned char *sig, - const unsigned char *m, - unsigned long m_len); + const unsigned char *sig, + const unsigned char *m, + unsigned long m_len); int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char *sig); + const unsigned char *hash, + unsigned long hash_len, + unsigned char *sig); #define _libssh2_dsa_free(dsactx) DSA_free(dsactx) @@ -206,15 +206,15 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, #define _libssh2_cipher_3des EVP_des_ede3_cbc int _libssh2_cipher_init (_libssh2_cipher_ctx *h, - _libssh2_cipher_type(algo), - unsigned char *iv, - unsigned char *secret, - int encrypt); + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, + int encrypt); int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, - _libssh2_cipher_type(algo), - int encrypt, - unsigned char *block); + _libssh2_cipher_type(algo), + int encrypt, + unsigned char *block); #define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx) diff --git a/src/packet.c b/src/packet.c index 699b69a..fb01d8c 100644 --- a/src/packet.c +++ b/src/packet.c @@ -65,131 +65,131 @@ static inline int libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data, unsigned long datalen) { - /* Look for a matching listener */ - unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5; - /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ - unsigned long packet_len = 17 + (sizeof("Forward not requested") - 1); - unsigned char *p, packet[17 + (sizeof("Forward not requested") - 1)]; - LIBSSH2_LISTENER *l = session->listeners; - char failure_code = 1; /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */ - uint32_t sender_channel, initial_window_size, packet_size; - unsigned char *host, *shost; - uint32_t port, sport, host_len, shost_len; - (void)datalen; - - sender_channel = libssh2_ntohu32(s); s += 4; - - initial_window_size = libssh2_ntohu32(s); s += 4; - packet_size = libssh2_ntohu32(s); s += 4; - - host_len = libssh2_ntohu32(s); s += 4; - host = s; s += host_len; - port = libssh2_ntohu32(s); s += 4; - - shost_len = libssh2_ntohu32(s); s += 4; - shost = s; s += shost_len; - sport = libssh2_ntohu32(s); s += 4; - - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Remote received connection from %s:%ld to %s:%ld", shost, sport, host, port); - - while (l) { - if ((l->port == (int)port) && - (strlen(l->host) == host_len) && - (memcmp(l->host, host, host_len) == 0)) { - /* This is our listener */ - LIBSSH2_CHANNEL *channel, *last_queued = l->queue; - - if (l->queue_maxsize && - (l->queue_maxsize <= l->queue_size)) { - /* Queue is full */ - failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Listener queue full, ignoring"); - break; - } - - channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); - if (!channel) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for new connection", 0); - failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ - break; - } - memset(channel, 0, sizeof(LIBSSH2_CHANNEL)); - - channel->session = session; - channel->channel_type_len = sizeof("forwarded-tcpip") - 1; - channel->channel_type = LIBSSH2_ALLOC(session, channel->channel_type_len + 1); - if (!channel->channel_type) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for new connection", 0); - LIBSSH2_FREE(session, channel); - failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ - break; - } - memcpy(channel->channel_type, "forwarded-tcpip", channel->channel_type_len + 1); - - channel->remote.id = sender_channel; - channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT; - channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT; - channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT; - - channel->local.id = libssh2_channel_nextid(session); - channel->local.window_size_initial = initial_window_size; - channel->local.window_size = initial_window_size; - channel->local.packet_size = packet_size; - - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Connection queued: channel %lu/%lu win %lu/%lu packet %lu/%lu", - channel->local.id, channel->remote.id, - channel->local.window_size, channel->remote.window_size, - channel->local.packet_size, channel->remote.packet_size); - - p = packet; - *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; - libssh2_htonu32(p, channel->remote.id); p += 4; - libssh2_htonu32(p, channel->local.id); p += 4; - libssh2_htonu32(p, channel->remote.window_size_initial); p += 4; - libssh2_htonu32(p, channel->remote.packet_size); p += 4; - - if (libssh2_packet_write(session, packet, 17)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel open confirmation", 0); - return -1; - } - - /* Link the channel into the end of the queue list */ - - if (!last_queued) { - l->queue = channel; - return 0; - } - - while (last_queued->next) last_queued = last_queued->next; - - last_queued->next = channel; - channel->prev = last_queued; - - l->queue_size++; - - return 0; - } - - l = l->next; - } - - /* We're not listening to you */ - { - - p = packet; - *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; - libssh2_htonu32(p, sender_channel); p += 4; - libssh2_htonu32(p, failure_code); p += 4; - libssh2_htonu32(p, sizeof("Forward not requested") - 1); p += 4; - memcpy(s, "Forward not requested", sizeof("Forward not requested") - 1); p += sizeof("Forward not requested") - 1; - libssh2_htonu32(p, 0); - - if (libssh2_packet_write(session, packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send open failure", 0); - return -1; - } + /* Look for a matching listener */ + unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5; + /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ + unsigned long packet_len = 17 + (sizeof("Forward not requested") - 1); + unsigned char *p, packet[17 + (sizeof("Forward not requested") - 1)]; + LIBSSH2_LISTENER *l = session->listeners; + char failure_code = 1; /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */ + uint32_t sender_channel, initial_window_size, packet_size; + unsigned char *host, *shost; + uint32_t port, sport, host_len, shost_len; + (void)datalen; + + sender_channel = libssh2_ntohu32(s); s += 4; + + initial_window_size = libssh2_ntohu32(s); s += 4; + packet_size = libssh2_ntohu32(s); s += 4; + + host_len = libssh2_ntohu32(s); s += 4; + host = s; s += host_len; + port = libssh2_ntohu32(s); s += 4; + + shost_len = libssh2_ntohu32(s); s += 4; + shost = s; s += shost_len; + sport = libssh2_ntohu32(s); s += 4; + + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Remote received connection from %s:%ld to %s:%ld", shost, sport, host, port); + + while (l) { + if ((l->port == (int)port) && + (strlen(l->host) == host_len) && + (memcmp(l->host, host, host_len) == 0)) { + /* This is our listener */ + LIBSSH2_CHANNEL *channel, *last_queued = l->queue; + + if (l->queue_maxsize && + (l->queue_maxsize <= l->queue_size)) { + /* Queue is full */ + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Listener queue full, ignoring"); + break; + } + + channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if (!channel) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for new connection", 0); + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ + break; + } + memset(channel, 0, sizeof(LIBSSH2_CHANNEL)); + + channel->session = session; + channel->channel_type_len = sizeof("forwarded-tcpip") - 1; + channel->channel_type = LIBSSH2_ALLOC(session, channel->channel_type_len + 1); + if (!channel->channel_type) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for new connection", 0); + LIBSSH2_FREE(session, channel); + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ + break; + } + memcpy(channel->channel_type, "forwarded-tcpip", channel->channel_type_len + 1); + + channel->remote.id = sender_channel; + channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT; + + channel->local.id = libssh2_channel_nextid(session); + channel->local.window_size_initial = initial_window_size; + channel->local.window_size = initial_window_size; + channel->local.packet_size = packet_size; + + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Connection queued: channel %lu/%lu win %lu/%lu packet %lu/%lu", + channel->local.id, channel->remote.id, + channel->local.window_size, channel->remote.window_size, + channel->local.packet_size, channel->remote.packet_size); + + p = packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; + libssh2_htonu32(p, channel->remote.id); p += 4; + libssh2_htonu32(p, channel->local.id); p += 4; + libssh2_htonu32(p, channel->remote.window_size_initial); p += 4; + libssh2_htonu32(p, channel->remote.packet_size); p += 4; + + if (libssh2_packet_write(session, packet, 17)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel open confirmation", 0); + return -1; + } + + /* Link the channel into the end of the queue list */ + + if (!last_queued) { + l->queue = channel; return 0; + } + + while (last_queued->next) last_queued = last_queued->next; + + last_queued->next = channel; + channel->prev = last_queued; + + l->queue_size++; + + return 0; } + + l = l->next; + } + + /* We're not listening to you */ + { + + p = packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; + libssh2_htonu32(p, sender_channel); p += 4; + libssh2_htonu32(p, failure_code); p += 4; + libssh2_htonu32(p, sizeof("Forward not requested") - 1); p += 4; + memcpy(s, "Forward not requested", sizeof("Forward not requested") - 1); p += sizeof("Forward not requested") - 1; + libssh2_htonu32(p, 0); + + if (libssh2_packet_write(session, packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send open failure", 0); + return -1; + } + return 0; + } } /* }}} */ @@ -199,107 +199,107 @@ static inline int libssh2_packet_queue_listener(LIBSSH2_SESSION *session, static inline int libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data, unsigned long datalen) { - int failure_code = 2; /* SSH_OPEN_CONNECT_FAILED */ - unsigned char *s = data + (sizeof("x11") - 1) + 5; - unsigned long packet_len = 17 + (sizeof("X11 Forward Unavailable") - 1); - unsigned char *p, packet[17 + (sizeof("X11 Forward Unavailable") - 1)]; - /* packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ - LIBSSH2_CHANNEL *channel; - unsigned long sender_channel, initial_window_size, packet_size; - unsigned char *shost; - unsigned long sport, shost_len; - (void)datalen; - - sender_channel = libssh2_ntohu32(s); s += 4; - initial_window_size = libssh2_ntohu32(s); s += 4; - packet_size = libssh2_ntohu32(s); s += 4; - shost_len = libssh2_ntohu32(s); s += 4; - shost = s; s += shost_len; - sport = libssh2_ntohu32(s); s += 4; - - _libssh2_debug(session, LIBSSH2_DBG_CONN, "X11 Connection Received from %s:%ld on channel %lu", shost, sport, sender_channel); - if (session->x11) { - channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); - if (!channel) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for new connection", 0); - failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ - goto x11_exit; - } - memset(channel, 0, sizeof(LIBSSH2_CHANNEL)); - - channel->session = session; - channel->channel_type_len = sizeof("x11") - 1; - channel->channel_type = LIBSSH2_ALLOC(session, channel->channel_type_len + 1); - if (!channel->channel_type) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for new connection", 0); - LIBSSH2_FREE(session, channel); - failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ - goto x11_exit; - } - memcpy(channel->channel_type, "x11", channel->channel_type_len + 1); - - channel->remote.id = sender_channel; - channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT; - channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT; - channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT; - - channel->local.id = libssh2_channel_nextid(session); - channel->local.window_size_initial = initial_window_size; - channel->local.window_size = initial_window_size; - channel->local.packet_size = packet_size; - + int failure_code = 2; /* SSH_OPEN_CONNECT_FAILED */ + unsigned char *s = data + (sizeof("x11") - 1) + 5; + unsigned long packet_len = 17 + (sizeof("X11 Forward Unavailable") - 1); + unsigned char *p, packet[17 + (sizeof("X11 Forward Unavailable") - 1)]; + /* packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ + LIBSSH2_CHANNEL *channel; + unsigned long sender_channel, initial_window_size, packet_size; + unsigned char *shost; + unsigned long sport, shost_len; + (void)datalen; + + sender_channel = libssh2_ntohu32(s); s += 4; + initial_window_size = libssh2_ntohu32(s); s += 4; + packet_size = libssh2_ntohu32(s); s += 4; + shost_len = libssh2_ntohu32(s); s += 4; + shost = s; s += shost_len; + sport = libssh2_ntohu32(s); s += 4; + + _libssh2_debug(session, LIBSSH2_DBG_CONN, "X11 Connection Received from %s:%ld on channel %lu", shost, sport, sender_channel); + if (session->x11) { + channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if (!channel) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for new connection", 0); + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ + goto x11_exit; + } + memset(channel, 0, sizeof(LIBSSH2_CHANNEL)); + + channel->session = session; + channel->channel_type_len = sizeof("x11") - 1; + channel->channel_type = LIBSSH2_ALLOC(session, channel->channel_type_len + 1); + if (!channel->channel_type) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for new connection", 0); + LIBSSH2_FREE(session, channel); + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ + goto x11_exit; + } + memcpy(channel->channel_type, "x11", channel->channel_type_len + 1); + + channel->remote.id = sender_channel; + channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT; + + channel->local.id = libssh2_channel_nextid(session); + channel->local.window_size_initial = initial_window_size; + channel->local.window_size = initial_window_size; + channel->local.packet_size = packet_size; + _libssh2_debug(session, LIBSSH2_DBG_CONN, "X11 Connection established: channel %lu/%lu win %lu/%lu packet %lu/%lu", - channel->local.id, channel->remote.id, - channel->local.window_size, channel->remote.window_size, - channel->local.packet_size, channel->remote.packet_size); - p = packet; - *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; - libssh2_htonu32(p, channel->remote.id); p += 4; - libssh2_htonu32(p, channel->local.id); p += 4; - libssh2_htonu32(p, channel->remote.window_size_initial); p += 4; - libssh2_htonu32(p, channel->remote.packet_size); p += 4; - - if (libssh2_packet_write(session, packet, 17)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel open confirmation", 0); - return -1; - } - - /* Link the channel into the session */ - if (session->channels.tail) { - session->channels.tail->next = channel; - channel->prev = session->channels.tail; - } else { - session->channels.head = channel; - channel->prev = NULL; - } - channel->next = NULL; - session->channels.tail = channel; - - /* - * Pass control to the callback, they may turn right around and - * free the channel, or actually use it - */ - LIBSSH2_X11_OPEN(channel, (char *)shost, sport); - - return 0; - } else { - failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ - } - - x11_exit: + channel->local.id, channel->remote.id, + channel->local.window_size, channel->remote.window_size, + channel->local.packet_size, channel->remote.packet_size); p = packet; - *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; - libssh2_htonu32(p, sender_channel); p += 4; - libssh2_htonu32(p, failure_code); p += 4; - libssh2_htonu32(p, sizeof("X11 Forward Unavailable") - 1); p += 4; - memcpy(s, "X11 Forward Unavailable", sizeof("X11 Forward Unavailable") - 1); p += sizeof("X11 Forward Unavailable") - 1; - libssh2_htonu32(p, 0); - - if (libssh2_packet_write(session, packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send open failure", 0); - return -1; + *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; + libssh2_htonu32(p, channel->remote.id); p += 4; + libssh2_htonu32(p, channel->local.id); p += 4; + libssh2_htonu32(p, channel->remote.window_size_initial); p += 4; + libssh2_htonu32(p, channel->remote.packet_size); p += 4; + + if (libssh2_packet_write(session, packet, 17)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel open confirmation", 0); + return -1; } + + /* Link the channel into the session */ + if (session->channels.tail) { + session->channels.tail->next = channel; + channel->prev = session->channels.tail; + } else { + session->channels.head = channel; + channel->prev = NULL; + } + channel->next = NULL; + session->channels.tail = channel; + + /* + * Pass control to the callback, they may turn right around and + * free the channel, or actually use it + */ + LIBSSH2_X11_OPEN(channel, (char *)shost, sport); + return 0; + } else { + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ + } + +x11_exit: + p = packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; + libssh2_htonu32(p, sender_channel); p += 4; + libssh2_htonu32(p, failure_code); p += 4; + libssh2_htonu32(p, sizeof("X11 Forward Unavailable") - 1); p += 4; + memcpy(s, "X11 Forward Unavailable", sizeof("X11 Forward Unavailable") - 1); p += sizeof("X11 Forward Unavailable") - 1; + libssh2_htonu32(p, 0); + + if (libssh2_packet_write(session, packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send open failure", 0); + return -1; + } + return 0; } /* }}} */ @@ -308,290 +308,290 @@ static inline int libssh2_packet_x11_open(LIBSSH2_SESSION *session, */ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, size_t datalen, int macstate) { - LIBSSH2_PACKET *packet; - unsigned long data_head = 0; - - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Packet type %d received, length=%d", (int)data[0], (int)datalen); - if (macstate == LIBSSH2_MAC_INVALID) { - if (session->macerror) { - if (LIBSSH2_MACERROR(session, (char *)data, datalen) == 0) { - /* Calling app has given the OK, Process it anyway */ - macstate = LIBSSH2_MAC_CONFIRMED; - } else { - libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC, "Invalid Message Authentication Code received", 0); - if (session->ssh_msg_disconnect) { - LIBSSH2_DISCONNECT(session, SSH_DISCONNECT_MAC_ERROR, "Invalid MAC received", sizeof("Invalid MAC received") - 1, "", 0); - } - LIBSSH2_FREE(session, data); - return -1; - } - } else { - libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC, "Invalid Message Authentication Code received", 0); - if (session->ssh_msg_disconnect) { - LIBSSH2_DISCONNECT(session, SSH_DISCONNECT_MAC_ERROR, "Invalid MAC received", sizeof("Invalid MAC received") - 1, "", 0); - } - LIBSSH2_FREE(session, data); - return -1; + LIBSSH2_PACKET *packet; + unsigned long data_head = 0; + + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Packet type %d received, length=%d", (int)data[0], (int)datalen); + if (macstate == LIBSSH2_MAC_INVALID) { + if (session->macerror) { + if (LIBSSH2_MACERROR(session, (char *)data, datalen) == 0) { + /* Calling app has given the OK, Process it anyway */ + macstate = LIBSSH2_MAC_CONFIRMED; + } else { + libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC, "Invalid Message Authentication Code received", 0); + if (session->ssh_msg_disconnect) { + LIBSSH2_DISCONNECT(session, SSH_DISCONNECT_MAC_ERROR, "Invalid MAC received", sizeof("Invalid MAC received") - 1, "", 0); } - } - - /* A couple exceptions to the packet adding rule: */ - switch (data[0]) { - case SSH_MSG_DISCONNECT: - { - char *message, *language; - int reason, message_len, language_len; - - reason = libssh2_ntohu32(data + 1); - message_len = libssh2_ntohu32(data + 5); - message = (char *)data + 9; /* packet_type(1) + reason(4) + message_len(4) */ - language_len = libssh2_ntohu32(data + 9 + message_len); - /* This is where we hack on the data a little, - * Use the MSB of language_len to to a terminating NULL (In all liklihood it is already) - * Shift the language tag back a byte (In all likelihood it's zero length anyway - * Store a NULL in the last byte of the packet to terminate the language string - * With the lengths passed this isn't *REALLY* necessary, but it's "kind" - */ - message[message_len] = '\0'; - language = (char *)data + 9 + message_len + 3; - if (language_len) { - memcpy(language, language + 1, language_len); - } - language[language_len] = '\0'; - - if (session->ssh_msg_disconnect) { - LIBSSH2_DISCONNECT(session, reason, message, message_len, language, language_len); - } - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Disconnect(%d): %s(%s)", reason, message, language); - LIBSSH2_FREE(session, data); - session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; - return -1; - } - break; - case SSH_MSG_IGNORE: - /* As with disconnect, back it up one and add a trailing NULL */ - memcpy(data + 4, data + 5, datalen - 5); - data[datalen] = '\0'; - if (session->ssh_msg_ignore) { - LIBSSH2_IGNORE(session, (char *)data + 4, datalen - 5); - } - LIBSSH2_FREE(session, data); - return 0; - break; - case SSH_MSG_DEBUG: - { - int always_display = data[0]; - char *message, *language; - int message_len, language_len; - - message_len = libssh2_ntohu32(data + 2); - message = (char *)data + 6; /* packet_type(1) + display(1) + message_len(4) */ - language_len = libssh2_ntohu32(data + 6 + message_len); - /* This is where we hack on the data a little, - * Use the MSB of language_len to to a terminating NULL (In all liklihood it is already) - * Shift the language tag back a byte (In all likelihood it's zero length anyway - * Store a NULL in the last byte of the packet to terminate the language string - * With the lengths passed this isn't *REALLY* necessary, but it's "kind" - */ - message[message_len] = '\0'; - language = (char *)data + 6 + message_len + 3; - if (language_len) { - memcpy(language, language + 1, language_len); - } - language[language_len] = '\0'; - - if (session->ssh_msg_debug) { - LIBSSH2_DEBUG(session, always_display, message, message_len, language, language_len); - } - /* _libssh2_debug will actually truncate this for us so that it's not an inordinate about of data */ - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Debug Packet: %s", message); - LIBSSH2_FREE(session, data); - return 0; - } - break; - case SSH_MSG_CHANNEL_EXTENDED_DATA: - data_head += 4; /* streamid(4) */ - case SSH_MSG_CHANNEL_DATA: - data_head += 9; /* packet_type(1) + channelno(4) + datalen(4) */ - { - LIBSSH2_CHANNEL *channel = libssh2_channel_locate(session, libssh2_ntohu32(data + 1)); - - if (!channel) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, "Packet received for unknown channel, ignoring", 0); - LIBSSH2_FREE(session, data); - return 0; - } -#ifdef LIBSSH2DEBUG -{ - unsigned long stream_id = 0; - - if (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) { - stream_id = libssh2_ntohu32(data + 5); - } - - _libssh2_debug(session, LIBSSH2_DBG_CONN, "%d bytes received for channel %lu/%lu stream #%lu", (int)(datalen - data_head), channel->local.id, channel->remote.id, stream_id); -} -#endif - if ((channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) && (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) { - /* Pretend we didn't receive this */ - LIBSSH2_FREE(session, data); - - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Ignoring extended data and refunding %d bytes", (int)(datalen - 13)); - /* Adjust the window based on the block we just freed */ - libssh2_channel_receive_window_adjust(channel, datalen - 13, 0); - - return 0; - } - - /* REMEMBER! remote means remote as source of data, NOT remote window! */ - if (channel->remote.packet_size < (datalen - data_head)) { - /* Spec says we MAY ignore bytes sent beyond packet_size */ - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, "Packet contains more data than we offered to receive, truncating", 0); - datalen = channel->remote.packet_size + data_head; - } - if (channel->remote.window_size <= 0) { - /* Spec says we MAY ignore bytes sent beyond window_size */ - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, "The current receive window is full, data ignored", 0); - LIBSSH2_FREE(session, data); - return 0; - } - /* Reset EOF status */ - channel->remote.eof = 0; - - if ((datalen - data_head) > channel->remote.window_size) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, "Remote sent more data than current window allows, truncating", 0); - datalen = channel->remote.window_size + data_head; - } else { - /* Now that we've received it, shrink our window */ - channel->remote.window_size -= datalen - data_head; - } - } - break; - case SSH_MSG_CHANNEL_EOF: - { - LIBSSH2_CHANNEL *channel = libssh2_channel_locate(session, libssh2_ntohu32(data + 1)); - - if (!channel) { - /* We may have freed already, just quietly ignore this... */ - LIBSSH2_FREE(session, data); - return 0; - } - - _libssh2_debug(session, LIBSSH2_DBG_CONN, "EOF received for channel %lu/%lu", channel->local.id, channel->remote.id); - channel->remote.eof = 1; - - LIBSSH2_FREE(session, data); - return 0; - } - break; - case SSH_MSG_CHANNEL_REQUEST: - { - if (libssh2_ntohu32(data+5) == sizeof("exit-status") - 1 - && !memcmp("exit-status", data + 9, sizeof("exit-status") - 1)) { - - /* we've got "exit-status" packet. Set the session value */ - LIBSSH2_CHANNEL *channel = libssh2_channel_locate(session, libssh2_ntohu32(data+1)); - - if (channel) { - channel->exit_status = libssh2_ntohu32(data + 9 + sizeof("exit-status")); - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Exit status %lu received for channel %lu/%lu", channel->exit_status, channel->local.id, channel->remote.id); - } - - LIBSSH2_FREE(session, data); - return 0; - } - } - break; - case SSH_MSG_CHANNEL_CLOSE: - { - LIBSSH2_CHANNEL *channel = libssh2_channel_locate(session, libssh2_ntohu32(data + 1)); - - if (!channel) { - /* We may have freed already, just quietly ignore this... */ - LIBSSH2_FREE(session, data); - return 0; - } - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Close received for channel %lu/%lu", channel->local.id, channel->remote.id); - - channel->remote.close = 1; - channel->remote.eof = 1; - /* TODO: Add a callback for this */ - - LIBSSH2_FREE(session, data); - return 0; - } - break; - case SSH_MSG_CHANNEL_OPEN: - if ((datalen >= (sizeof("forwarded-tcpip") + 4)) && - ((sizeof("forwarded-tcpip")-1) == libssh2_ntohu32(data + 1)) && - (memcmp(data + 5, "forwarded-tcpip", sizeof("forwarded-tcpip") - 1) == 0)) { - int retval = libssh2_packet_queue_listener(session, data, datalen); - - LIBSSH2_FREE(session, data); - return retval; - } - if ((datalen >= (sizeof("x11") + 4)) && - ((sizeof("x11")-1) == libssh2_ntohu32(data + 1)) && - (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) { - int retval = libssh2_packet_x11_open(session, data, datalen); - - LIBSSH2_FREE(session, data); - return retval; - } - break; - case SSH_MSG_CHANNEL_WINDOW_ADJUST: - { - LIBSSH2_CHANNEL *channel = libssh2_channel_locate(session, libssh2_ntohu32(data + 1)); - unsigned long bytestoadd = libssh2_ntohu32(data + 5); - - if (channel && bytestoadd) { - channel->local.window_size += bytestoadd; - } - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Window adjust received for channel %lu/%lu, adding %lu bytes, new window_size=%lu", channel->local.id, channel->remote.id, bytestoadd, channel->local.window_size); - - LIBSSH2_FREE(session, data); - return 0; - } - break; - } - - packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); - if (!packet) { - _libssh2_debug(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for LIBSSH2_PACKET"); - LIBSSH2_FREE(session, data); - return -1; - } - memset(packet, 0, sizeof(LIBSSH2_PACKET)); - - packet->data = data; - packet->data_len = datalen; - packet->data_head = data_head; - packet->mac = macstate; - packet->brigade = &session->packets; - packet->next = NULL; - - if (session->packets.tail) { - packet->prev = session->packets.tail; - packet->prev->next = packet; - session->packets.tail = packet; + LIBSSH2_FREE(session, data); + return -1; + } } else { - session->packets.head = packet; - session->packets.tail = packet; - packet->prev = NULL; + libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC, "Invalid Message Authentication Code received", 0); + if (session->ssh_msg_disconnect) { + LIBSSH2_DISCONNECT(session, SSH_DISCONNECT_MAC_ERROR, "Invalid MAC received", sizeof("Invalid MAC received") - 1, "", 0); + } + LIBSSH2_FREE(session, data); + return -1; } - - if (data[0] == SSH_MSG_KEXINIT && !(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) { - /* Remote wants new keys - * Well, it's already in the brigade, - * let's just call back into ourselves + } + + /* A couple exceptions to the packet adding rule: */ + switch (data[0]) { + case SSH_MSG_DISCONNECT: + { + char *message, *language; + int reason, message_len, language_len; + + reason = libssh2_ntohu32(data + 1); + message_len = libssh2_ntohu32(data + 5); + message = (char *)data + 9; /* packet_type(1) + reason(4) + message_len(4) */ + language_len = libssh2_ntohu32(data + 9 + message_len); + /* This is where we hack on the data a little, + * Use the MSB of language_len to to a terminating NULL (In all liklihood it is already) + * Shift the language tag back a byte (In all likelihood it's zero length anyway + * Store a NULL in the last byte of the packet to terminate the language string + * With the lengths passed this isn't *REALLY* necessary, but it's "kind" */ - _libssh2_debug(session, LIBSSH2_DBG_TRANS, - "Renegotiating Keys"); - libssh2_kex_exchange(session, 1); - /* If there was a key reexchange failure, let's just hope we didn't send NEWKEYS yet, otherwise remote will drop us like a rock */ + message[message_len] = '\0'; + language = (char *)data + 9 + message_len + 3; + if (language_len) { + memcpy(language, language + 1, language_len); + } + language[language_len] = '\0'; + + if (session->ssh_msg_disconnect) { + LIBSSH2_DISCONNECT(session, reason, message, message_len, language, language_len); + } + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Disconnect(%d): %s(%s)", reason, message, language); + LIBSSH2_FREE(session, data); + session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; + return -1; + } + break; + case SSH_MSG_IGNORE: + /* As with disconnect, back it up one and add a trailing NULL */ + memcpy(data + 4, data + 5, datalen - 5); + data[datalen] = '\0'; + if (session->ssh_msg_ignore) { + LIBSSH2_IGNORE(session, (char *)data + 4, datalen - 5); + } + LIBSSH2_FREE(session, data); + return 0; + break; + case SSH_MSG_DEBUG: + { + int always_display = data[0]; + char *message, *language; + int message_len, language_len; + + message_len = libssh2_ntohu32(data + 2); + message = (char *)data + 6; /* packet_type(1) + display(1) + message_len(4) */ + language_len = libssh2_ntohu32(data + 6 + message_len); + /* This is where we hack on the data a little, + * Use the MSB of language_len to to a terminating NULL (In all liklihood it is already) + * Shift the language tag back a byte (In all likelihood it's zero length anyway + * Store a NULL in the last byte of the packet to terminate the language string + * With the lengths passed this isn't *REALLY* necessary, but it's "kind" + */ + message[message_len] = '\0'; + language = (char *)data + 6 + message_len + 3; + if (language_len) { + memcpy(language, language + 1, language_len); + } + language[language_len] = '\0'; + + if (session->ssh_msg_debug) { + LIBSSH2_DEBUG(session, always_display, message, message_len, language, language_len); + } + /* _libssh2_debug will actually truncate this for us so that it's not an inordinate about of data */ + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Debug Packet: %s", message); + LIBSSH2_FREE(session, data); + return 0; + } + break; + case SSH_MSG_CHANNEL_EXTENDED_DATA: + data_head += 4; /* streamid(4) */ + case SSH_MSG_CHANNEL_DATA: + data_head += 9; /* packet_type(1) + channelno(4) + datalen(4) */ + { + LIBSSH2_CHANNEL *channel = libssh2_channel_locate(session, libssh2_ntohu32(data + 1)); + + if (!channel) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, "Packet received for unknown channel, ignoring", 0); + LIBSSH2_FREE(session, data); + return 0; + } +#ifdef LIBSSH2DEBUG + { + unsigned long stream_id = 0; + + if (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) { + stream_id = libssh2_ntohu32(data + 5); + } + + _libssh2_debug(session, LIBSSH2_DBG_CONN, "%d bytes received for channel %lu/%lu stream #%lu", (int)(datalen - data_head), channel->local.id, channel->remote.id, stream_id); + } +#endif + if ((channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) && (data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) { + /* Pretend we didn't receive this */ + LIBSSH2_FREE(session, data); + + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Ignoring extended data and refunding %d bytes", (int)(datalen - 13)); + /* Adjust the window based on the block we just freed */ + libssh2_channel_receive_window_adjust(channel, datalen - 13, 0); + + return 0; + } + + /* REMEMBER! remote means remote as source of data, NOT remote window! */ + if (channel->remote.packet_size < (datalen - data_head)) { + /* Spec says we MAY ignore bytes sent beyond packet_size */ + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, "Packet contains more data than we offered to receive, truncating", 0); + datalen = channel->remote.packet_size + data_head; + } + if (channel->remote.window_size <= 0) { + /* Spec says we MAY ignore bytes sent beyond window_size */ + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, "The current receive window is full, data ignored", 0); + LIBSSH2_FREE(session, data); + return 0; + } + /* Reset EOF status */ + channel->remote.eof = 0; + + if ((datalen - data_head) > channel->remote.window_size) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, "Remote sent more data than current window allows, truncating", 0); + datalen = channel->remote.window_size + data_head; + } else { + /* Now that we've received it, shrink our window */ + channel->remote.window_size -= datalen - data_head; + } + } + break; + case SSH_MSG_CHANNEL_EOF: + { + LIBSSH2_CHANNEL *channel = libssh2_channel_locate(session, libssh2_ntohu32(data + 1)); + + if (!channel) { + /* We may have freed already, just quietly ignore this... */ + LIBSSH2_FREE(session, data); + return 0; + } + + _libssh2_debug(session, LIBSSH2_DBG_CONN, "EOF received for channel %lu/%lu", channel->local.id, channel->remote.id); + channel->remote.eof = 1; + + LIBSSH2_FREE(session, data); + return 0; + } + break; + case SSH_MSG_CHANNEL_REQUEST: + { + if (libssh2_ntohu32(data+5) == sizeof("exit-status") - 1 + && !memcmp("exit-status", data + 9, sizeof("exit-status") - 1)) { + + /* we've got "exit-status" packet. Set the session value */ + LIBSSH2_CHANNEL *channel = libssh2_channel_locate(session, libssh2_ntohu32(data+1)); + + if (channel) { + channel->exit_status = libssh2_ntohu32(data + 9 + sizeof("exit-status")); + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Exit status %lu received for channel %lu/%lu", channel->exit_status, channel->local.id, channel->remote.id); + } + + LIBSSH2_FREE(session, data); + return 0; + } + } + break; + case SSH_MSG_CHANNEL_CLOSE: + { + LIBSSH2_CHANNEL *channel = libssh2_channel_locate(session, libssh2_ntohu32(data + 1)); + + if (!channel) { + /* We may have freed already, just quietly ignore this... */ + LIBSSH2_FREE(session, data); + return 0; + } + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Close received for channel %lu/%lu", channel->local.id, channel->remote.id); + + channel->remote.close = 1; + channel->remote.eof = 1; + /* TODO: Add a callback for this */ + + LIBSSH2_FREE(session, data); + return 0; + } + break; + case SSH_MSG_CHANNEL_OPEN: + if ((datalen >= (sizeof("forwarded-tcpip") + 4)) && + ((sizeof("forwarded-tcpip")-1) == libssh2_ntohu32(data + 1)) && + (memcmp(data + 5, "forwarded-tcpip", sizeof("forwarded-tcpip") - 1) == 0)) { + int retval = libssh2_packet_queue_listener(session, data, datalen); + + LIBSSH2_FREE(session, data); + return retval; + } + if ((datalen >= (sizeof("x11") + 4)) && + ((sizeof("x11")-1) == libssh2_ntohu32(data + 1)) && + (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) { + int retval = libssh2_packet_x11_open(session, data, datalen); + + LIBSSH2_FREE(session, data); + return retval; + } + break; + case SSH_MSG_CHANNEL_WINDOW_ADJUST: + { + LIBSSH2_CHANNEL *channel = libssh2_channel_locate(session, libssh2_ntohu32(data + 1)); + unsigned long bytestoadd = libssh2_ntohu32(data + 5); + + if (channel && bytestoadd) { + channel->local.window_size += bytestoadd; + } + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Window adjust received for channel %lu/%lu, adding %lu bytes, new window_size=%lu", channel->local.id, channel->remote.id, bytestoadd, channel->local.window_size); + + LIBSSH2_FREE(session, data); + return 0; + } + break; } - - return 0; + + packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); + if (!packet) { + _libssh2_debug(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for LIBSSH2_PACKET"); + LIBSSH2_FREE(session, data); + return -1; + } + memset(packet, 0, sizeof(LIBSSH2_PACKET)); + + packet->data = data; + packet->data_len = datalen; + packet->data_head = data_head; + packet->mac = macstate; + packet->brigade = &session->packets; + packet->next = NULL; + + if (session->packets.tail) { + packet->prev = session->packets.tail; + packet->prev->next = packet; + session->packets.tail = packet; + } else { + session->packets.head = packet; + session->packets.tail = packet; + packet->prev = NULL; + } + + if (data[0] == SSH_MSG_KEXINIT && !(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) { + /* Remote wants new keys + * Well, it's already in the brigade, + * let's just call back into ourselves + */ + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "Renegotiating Keys"); + libssh2_kex_exchange(session, 1); + /* If there was a key reexchange failure, let's just hope we didn't send NEWKEYS yet, otherwise remote will drop us like a rock */ + } + + return 0; } /* }}} */ @@ -605,44 +605,44 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, const unsigned char *match_buf, unsigned long match_len, int poll_socket) { - LIBSSH2_PACKET *packet = session->packets.head; - - if (poll_socket) { - libssh2pack_t rc = libssh2_packet_read(session); - if ((rc < 0) && !packet) { - return rc; - } + LIBSSH2_PACKET *packet = session->packets.head; + + if (poll_socket) { + libssh2pack_t rc = libssh2_packet_read(session); + if ((rc < 0) && !packet) { + return rc; } - _libssh2_debug(session, LIBSSH2_DBG_TRANS, - "Looking for packet of type: %d", (int)packet_type); - - while (packet) { - if (packet->data[0] == packet_type && - (packet->data_len >= (match_ofs + match_len)) && - (!match_buf || - (memcmp(packet->data + match_ofs, match_buf, match_len) == 0))) { - *data = packet->data; - *data_len = packet->data_len; - - if (packet->prev) { - packet->prev->next = packet->next; - } else { - session->packets.head = packet->next; - } - - if (packet->next) { - packet->next->prev = packet->prev; - } else { - session->packets.tail = packet->prev; - } - - LIBSSH2_FREE(session, packet); - - return 0; - } - packet = packet->next; + } + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "Looking for packet of type: %d", (int)packet_type); + + while (packet) { + if (packet->data[0] == packet_type && + (packet->data_len >= (match_ofs + match_len)) && + (!match_buf || + (memcmp(packet->data + match_ofs, match_buf, match_len) == 0))) { + *data = packet->data; + *data_len = packet->data_len; + + if (packet->prev) { + packet->prev->next = packet->next; + } else { + session->packets.head = packet->next; + } + + if (packet->next) { + packet->next->prev = packet->prev; + } else { + session->packets.tail = packet->prev; + } + + LIBSSH2_FREE(session, packet); + + return 0; } - return -1; + packet = packet->next; + } + return -1; } /* }}} */ @@ -658,18 +658,18 @@ int libssh2_packet_askv_ex(LIBSSH2_SESSION *session, const unsigned char *match_buf, unsigned long match_len, int poll_socket) { - int i, packet_types_len = strlen((char *)packet_types); - - for(i = 0; i < packet_types_len; i++) { - if (0 == libssh2_packet_ask_ex(session, packet_types[i], - data, data_len, match_ofs, - match_buf, match_len, - i ? 0 : poll_socket)) { - return 0; - } + int i, packet_types_len = strlen((char *)packet_types); + + for(i = 0; i < packet_types_len; i++) { + if (0 == libssh2_packet_ask_ex(session, packet_types[i], + data, data_len, match_ofs, + match_buf, match_len, + i ? 0 : poll_socket)) { + return 0; } - - return -1; + } + + return -1; } /* }}} */ @@ -682,22 +682,22 @@ int libssh2_packet_askv_ex(LIBSSH2_SESSION *session, * FIXME: convert to use poll on systems that have it. */ int libssh2_waitsocket(LIBSSH2_SESSION *session, - long seconds) + long seconds) { - struct timeval timeout; - int rc; - fd_set fd; - - timeout.tv_sec = seconds; - timeout.tv_usec = 0; - - FD_ZERO(&fd); - - FD_SET(session->socket_fd, &fd); - - rc = select(session->socket_fd+1, &fd, NULL, NULL, &timeout); - - return rc; + struct timeval timeout; + int rc; + fd_set fd; + + timeout.tv_sec = seconds; + timeout.tv_usec = 0; + + FD_ZERO(&fd); + + FD_SET(session->socket_fd, &fd); + + rc = select(session->socket_fd+1, &fd, NULL, NULL, &timeout); + + return rc; } /* {{{ libssh2_packet_require @@ -716,47 +716,47 @@ int libssh2_packet_require_ex(LIBSSH2_SESSION *session, const unsigned char *match_buf, unsigned long match_len) { - time_t start = time(NULL); - - if (libssh2_packet_ask_ex(session, packet_type, data, data_len, - match_ofs, match_buf, match_len, 0) == 0) { - /* A packet was available in the packet brigade */ - return 0; + time_t start = time(NULL); + + if (libssh2_packet_ask_ex(session, packet_type, data, data_len, + match_ofs, match_buf, match_len, 0) == 0) { + /* A packet was available in the packet brigade */ + return 0; + } + + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "Blocking until packet of type %d becomes available", + (int)packet_type); + + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + libssh2pack_t ret = libssh2_packet_read(session); + if ((ret < 0) && (ret != PACKET_EAGAIN)) { + /* an error which is not just because of blocking */ + return ret; } - - _libssh2_debug(session, LIBSSH2_DBG_TRANS, - "Blocking until packet of type %d becomes available", - (int)packet_type); - - while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { - libssh2pack_t ret = libssh2_packet_read(session); - if ((ret < 0) && (ret != PACKET_EAGAIN)) { - /* an error which is not just because of blocking */ - return ret; - } - if (packet_type == ret) { - /* Be lazy, let packet_ask pull it out of the - brigade */ - ret = libssh2_packet_ask_ex(session, packet_type, - data, data_len, match_ofs, - match_buf, match_len, 0); - return ret; - } - else if (ret <= 0) { - /* nothing available, wait until data arrives or - we time out */ - long left = LIBSSH2_READ_TIMEOUT - - (time(NULL) - start); - - if((left <= 0) || - (libssh2_waitsocket(session, left) <= 0)) { - return PACKET_TIMEOUT; - } - } + if (packet_type == ret) { + /* Be lazy, let packet_ask pull it out of the + brigade */ + ret = libssh2_packet_ask_ex(session, packet_type, + data, data_len, match_ofs, + match_buf, match_len, 0); + return ret; } - - /* Only reached if the socket died */ - return -1; + else if (ret <= 0) { + /* nothing available, wait until data arrives or + we time out */ + long left = LIBSSH2_READ_TIMEOUT - + (time(NULL) - start); + + if((left <= 0) || + (libssh2_waitsocket(session, left) <= 0)) { + return PACKET_TIMEOUT; + } + } + } + + /* Only reached if the socket died */ + return -1; } /* }}} */ @@ -766,44 +766,44 @@ int libssh2_packet_require_ex(LIBSSH2_SESSION *session, */ int libssh2_packet_burn(LIBSSH2_SESSION *session) { - unsigned char *data; - unsigned long data_len; - unsigned char all_packets[255]; - int i; - for(i = 1; i < 256; i++) all_packets[i - 1] = i; - - if (libssh2_packet_askv_ex(session, all_packets, &data, &data_len, 0, - NULL, 0, 0) == 0) { - i = data[0]; - /* A packet was available in the packet brigade, burn it */ - LIBSSH2_FREE(session, data); - return i; + unsigned char *data; + unsigned long data_len; + unsigned char all_packets[255]; + int i; + for(i = 1; i < 256; i++) all_packets[i - 1] = i; + + if (libssh2_packet_askv_ex(session, all_packets, &data, &data_len, 0, + NULL, 0, 0) == 0) { + i = data[0]; + /* A packet was available in the packet brigade, burn it */ + LIBSSH2_FREE(session, data); + return i; + } + + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "Blocking until packet becomes available to burn"); + + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + int ret = libssh2_packet_read(session); + if (ret < 0) { + return ret; } - - _libssh2_debug(session, LIBSSH2_DBG_TRANS, - "Blocking until packet becomes available to burn"); - - while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { - int ret = libssh2_packet_read(session); - if (ret < 0) { - return ret; - } - if (ret == 0) { - /* FIXME: this might busyloop */ - continue; - } - - /* Be lazy, let packet_ask pull it out of the brigade */ - if (0 == libssh2_packet_ask_ex(session, ret, &data, &data_len, - 0, NULL, 0, 0)) { - /* Smoke 'em if you got 'em */ - LIBSSH2_FREE(session, data); - return ret; - } + if (ret == 0) { + /* FIXME: this might busyloop */ + continue; } - - /* Only reached if the socket died */ - return -1; + + /* Be lazy, let packet_ask pull it out of the brigade */ + if (0 == libssh2_packet_ask_ex(session, ret, &data, &data_len, + 0, NULL, 0, 0)) { + /* Smoke 'em if you got 'em */ + LIBSSH2_FREE(session, data); + return ret; + } + } + + /* Only reached if the socket died */ + return -1; } /* }}} */ @@ -822,41 +822,41 @@ int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *match_buf, unsigned long match_len) { - time_t start = time(NULL); - - if (libssh2_packet_askv_ex(session, packet_types, data, data_len, - match_ofs, match_buf, match_len, 0) == 0) { - /* One of the packets listed was available in the packet - brigade */ - return 0; + time_t start = time(NULL); + + if (libssh2_packet_askv_ex(session, packet_types, data, data_len, + match_ofs, match_buf, match_len, 0) == 0) { + /* One of the packets listed was available in the packet + brigade */ + return 0; + } + + while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) { + int ret = libssh2_packet_read(session); + if ((ret < 0) && (ret != PACKET_EAGAIN)) { + return ret; } - - while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) { - int ret = libssh2_packet_read(session); - if ((ret < 0) && (ret != PACKET_EAGAIN)) { - return ret; - } - if (ret <= 0) { - long left = LIBSSH2_READ_TIMEOUT - - (time(NULL) - start); - - if((left <= 0) || - (libssh2_waitsocket(session, left) <= 0 )) { - return PACKET_TIMEOUT; - } - } - - if (strchr((char *)packet_types, ret)) { - /* Be lazy, let packet_ask pull it out of the - brigade */ - return libssh2_packet_askv_ex(session, packet_types, - data, data_len, - match_ofs, match_buf, - match_len, 0); - } + if (ret <= 0) { + long left = LIBSSH2_READ_TIMEOUT - + (time(NULL) - start); + + if((left <= 0) || + (libssh2_waitsocket(session, left) <= 0 )) { + return PACKET_TIMEOUT; + } } - - /* Only reached if the socket died */ - return -1; + + if (strchr((char *)packet_types, ret)) { + /* Be lazy, let packet_ask pull it out of the + brigade */ + return libssh2_packet_askv_ex(session, packet_types, + data, data_len, + match_ofs, match_buf, + match_len, 0); + } + } + + /* Only reached if the socket died */ + return -1; } /* }}} */ diff --git a/src/pem.c b/src/pem.c index 03a907d..e85bbb0 100644 --- a/src/pem.c +++ b/src/pem.c @@ -39,191 +39,191 @@ static int readline (char *line, int line_size, FILE *fp) { - if (!fgets(line, line_size, fp)) - { - return -1; - } - if (*line && line[strlen(line) - 1] == '\r') - { - line[strlen(line) - 1] = '\0'; - } - if (*line && line[strlen(line) - 1] == '\n') - { - line[strlen(line) - 1] = '\0'; - } - return 0; + if (!fgets(line, line_size, fp)) + { + return -1; + } + if (*line && line[strlen(line) - 1] == '\r') + { + line[strlen(line) - 1] = '\0'; + } + if (*line && line[strlen(line) - 1] == '\n') + { + line[strlen(line) - 1] = '\0'; + } + return 0; } #define LINE_SIZE 128 int _libssh2_pem_parse (LIBSSH2_SESSION *session, - const char *headerbegin, - const char *headerend, - FILE *fp, - char **data, unsigned int *datalen) + const char *headerbegin, + const char *headerend, + FILE *fp, + char **data, unsigned int *datalen) { - char line[LINE_SIZE]; - char *b64data = NULL; - unsigned int b64datalen = 0; - int ret; + char line[LINE_SIZE]; + char *b64data = NULL; + unsigned int b64datalen = 0; + int ret; - do - { - if (readline(line, LINE_SIZE, fp)) - { - return -1; - } - } - while (strcmp (line, headerbegin) != 0); + do + { + if (readline(line, LINE_SIZE, fp)) + { + return -1; + } + } + while (strcmp (line, headerbegin) != 0); - *line = '\0'; + *line = '\0'; - do - { - if (*line) - { - char *tmp; - size_t linelen; + do + { + if (*line) + { + char *tmp; + size_t linelen; - linelen = strlen (line); - tmp = LIBSSH2_REALLOC (session, b64data, - b64datalen + linelen); - if (!tmp) - { - ret = -1; - goto out; - } - memcpy (tmp + b64datalen, line, linelen); - b64data = tmp; - b64datalen += linelen; - } + linelen = strlen (line); + tmp = LIBSSH2_REALLOC (session, b64data, + b64datalen + linelen); + if (!tmp) + { + ret = -1; + goto out; + } + memcpy (tmp + b64datalen, line, linelen); + b64data = tmp; + b64datalen += linelen; + } - if (readline(line, LINE_SIZE, fp)) - { - ret = -1; - goto out; - } - } while (strcmp (line, headerend) != 0); + if (readline(line, LINE_SIZE, fp)) + { + ret = -1; + goto out; + } + } while (strcmp (line, headerend) != 0); - if (libssh2_base64_decode(session, data, datalen, - b64data, b64datalen)) - { - ret = -1; - goto out; - } + if (libssh2_base64_decode(session, data, datalen, + b64data, b64datalen)) + { + ret = -1; + goto out; + } - ret = 0; + ret = 0; out: - if (b64data) { - LIBSSH2_FREE (session, b64data); - } - return ret; + if (b64data) { + LIBSSH2_FREE (session, b64data); + } + return ret; } static int read_asn1_length (const unsigned char *data, - unsigned int datalen, - unsigned int *len) + unsigned int datalen, + unsigned int *len) { - unsigned int lenlen; - int nextpos; + unsigned int lenlen; + int nextpos; - if (datalen < 1) - { - return -1; - } - *len = data[0]; + if (datalen < 1) + { + return -1; + } + *len = data[0]; - if (*len >= 0x80) - { - lenlen = *len & 0x7F; - *len = data[1]; - if (1 + lenlen > datalen) - { - return -1; - } - if (lenlen > 1) - { - *len <<= 8; - *len |= data[2]; - } - } - else - { - lenlen = 0; - } + if (*len >= 0x80) + { + lenlen = *len & 0x7F; + *len = data[1]; + if (1 + lenlen > datalen) + { + return -1; + } + if (lenlen > 1) + { + *len <<= 8; + *len |= data[2]; + } + } + else + { + lenlen = 0; + } - nextpos = 1 + lenlen; - if (lenlen > 2 || 1 + lenlen + *len > datalen) - { - return -1; - } + nextpos = 1 + lenlen; + if (lenlen > 2 || 1 + lenlen + *len > datalen) + { + return -1; + } - return nextpos; + return nextpos; } int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen) { - unsigned int len; - int lenlen; + unsigned int len; + int lenlen; - if (*datalen < 1) - { - return -1; - } + if (*datalen < 1) + { + return -1; + } - if ((*data)[0] != '\x30') - { - return -1; - } + if ((*data)[0] != '\x30') + { + return -1; + } - (*data)++; - (*datalen)--; + (*data)++; + (*datalen)--; - lenlen = read_asn1_length (*data, *datalen, &len); - if (lenlen < 0 || lenlen + len != *datalen) - { - return -1; - } + lenlen = read_asn1_length (*data, *datalen, &len); + if (lenlen < 0 || lenlen + len != *datalen) + { + return -1; + } - *data += lenlen; - *datalen -= lenlen; + *data += lenlen; + *datalen -= lenlen; - return 0; + return 0; } int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen, - unsigned char **i, unsigned int *ilen) + unsigned char **i, unsigned int *ilen) { - unsigned int len; - int lenlen; + unsigned int len; + int lenlen; - if (*datalen < 1) - { - return -1; - } + if (*datalen < 1) + { + return -1; + } - if ((*data)[0] != '\x02') - { - return -1; - } + if ((*data)[0] != '\x02') + { + return -1; + } - (*data)++; - (*datalen)--; + (*data)++; + (*datalen)--; - lenlen = read_asn1_length (*data, *datalen, &len); - if (lenlen < 0 || lenlen + len > *datalen) - { - return -1; - } + lenlen = read_asn1_length (*data, *datalen, &len); + if (lenlen < 0 || lenlen + len > *datalen) + { + return -1; + } - *data += lenlen; - *datalen -= lenlen; + *data += lenlen; + *datalen -= lenlen; - *i = *data; - *ilen = len; + *i = *data; + *ilen = len; - *data += len; - *datalen -= len; + *data += len; + *datalen -= len; - return 0; + return 0; } diff --git a/src/publickey.c b/src/publickey.c index a561a0d..3a7678e 100644 --- a/src/publickey.c +++ b/src/publickey.c @@ -39,100 +39,100 @@ #include "libssh2_publickey.h" struct _LIBSSH2_PUBLICKEY { - LIBSSH2_CHANNEL *channel; - unsigned long version; + LIBSSH2_CHANNEL *channel; + unsigned long version; }; -#define LIBSSH2_PUBLICKEY_VERSION 2 +#define LIBSSH2_PUBLICKEY_VERSION 2 /* Numericised response codes -- Not IETF standard, just a local representation */ -#define LIBSSH2_PUBLICKEY_RESPONSE_STATUS 0 -#define LIBSSH2_PUBLICKEY_RESPONSE_VERSION 1 -#define LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY 2 +#define LIBSSH2_PUBLICKEY_RESPONSE_STATUS 0 +#define LIBSSH2_PUBLICKEY_RESPONSE_VERSION 1 +#define LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY 2 typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST { - int code; - const char *name; - int name_len; + int code; + const char *name; + int name_len; } LIBSSH2_PUBLICKEY_CODE_LIST; static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_response_codes[] = { - { LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1 }, - { LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1 }, - { LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", sizeof("publickey") - 1 }, - { 0, NULL, 0 } + { LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1 }, + { LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1 }, + { LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", sizeof("publickey") - 1 }, + { 0, NULL, 0 } }; /* PUBLICKEY status codes -- IETF defined */ -#define LIBSSH2_PUBLICKEY_SUCCESS 0 -#define LIBSSH2_PUBLICKEY_ACCESS_DENIED 1 -#define LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED 2 -#define LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED 3 -#define LIBSSH2_PUBLICKEY_KEY_NOT_FOUND 4 -#define LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED 5 -#define LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT 6 -#define LIBSSH2_PUBLICKEY_GENERAL_FAILURE 7 -#define LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED 8 +#define LIBSSH2_PUBLICKEY_SUCCESS 0 +#define LIBSSH2_PUBLICKEY_ACCESS_DENIED 1 +#define LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED 2 +#define LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED 3 +#define LIBSSH2_PUBLICKEY_KEY_NOT_FOUND 4 +#define LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED 5 +#define LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT 6 +#define LIBSSH2_PUBLICKEY_GENERAL_FAILURE 7 +#define LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED 8 -#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8 +#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8 static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = { - { LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1 }, - { LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied", sizeof("access denied") - 1 }, - { LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded", sizeof("storage exceeded") - 1 }, - { LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported", sizeof("version not supported") - 1 }, - { LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found", sizeof("key not found") - 1 }, - { LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported", sizeof("key not supported") - 1 }, - { LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT, "key already present", sizeof("key already present") - 1 }, - { LIBSSH2_PUBLICKEY_GENERAL_FAILURE, "general failure", sizeof("general failure") - 1 }, - { LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED, "request not supported", sizeof("request not supported") - 1 }, - { 0, NULL, 0 } + { LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1 }, + { LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied", sizeof("access denied") - 1 }, + { LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded", sizeof("storage exceeded") - 1 }, + { LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported", sizeof("version not supported") - 1 }, + { LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found", sizeof("key not found") - 1 }, + { LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported", sizeof("key not supported") - 1 }, + { LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT, "key already present", sizeof("key already present") - 1 }, + { LIBSSH2_PUBLICKEY_GENERAL_FAILURE, "general failure", sizeof("general failure") - 1 }, + { LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED, "request not supported", sizeof("request not supported") - 1 }, + { 0, NULL, 0 } }; /* {{{ libssh2_publickey_status_error * Format an error message from a status code */ -#define LIBSSH2_PUBLICKEY_STATUS_TEXT_START "Publickey Subsystem Error: \"" -#define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID "\" Server Resports: \"" -#define LIBSSH2_PUBLICKEY_STATUS_TEXT_END "\"" +#define LIBSSH2_PUBLICKEY_STATUS_TEXT_START "Publickey Subsystem Error: \"" +#define LIBSSH2_PUBLICKEY_STATUS_TEXT_MID "\" Server Resports: \"" +#define LIBSSH2_PUBLICKEY_STATUS_TEXT_END "\"" static void libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, LIBSSH2_SESSION *session, int status, const unsigned char *message, int message_len) { - const char *status_text; - int status_text_len; - char *m, *s; - int m_len; + const char *status_text; + int status_text_len; + char *m, *s; + int m_len; - /* GENERAL_FAILURE got remapped between version 1 and 2 */ - if (status == 6 && pkey && pkey->version == 1) { - status = 7; - } + /* GENERAL_FAILURE got remapped between version 1 and 2 */ + if (status == 6 && pkey && pkey->version == 1) { + status = 7; + } - if (status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) { - status_text = "unknown"; - status_text_len = sizeof("unknown") - 1; - } else { - status_text = libssh2_publickey_status_codes[status].name; - status_text_len = libssh2_publickey_status_codes[status].name_len; - } + if (status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) { + status_text = "unknown"; + status_text_len = sizeof("unknown") - 1; + } else { + status_text = libssh2_publickey_status_codes[status].name; + status_text_len = libssh2_publickey_status_codes[status].name_len; + } - m_len = (sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1) + status_text_len + - (sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1) + message_len + - (sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END) - 1); - m = LIBSSH2_ALLOC(session, m_len + 1); - if (!m) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for status message", 0); - return; - } - s = m; - memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_START, sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1); - s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1; - memcpy(s, status_text, status_text_len); s += status_text_len; - memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_MID, sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1); - s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1; - memcpy(s, message, message_len); s += message_len; - memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_END, sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END) - 1); - s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END); - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, m, 1); + m_len = (sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1) + status_text_len + + (sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1) + message_len + + (sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END) - 1); + m = LIBSSH2_ALLOC(session, m_len + 1); + if (!m) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for status message", 0); + return; + } + s = m; + memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_START, sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1); + s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_START) - 1; + memcpy(s, status_text, status_text_len); s += status_text_len; + memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_MID, sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1); + s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_MID) - 1; + memcpy(s, message, message_len); s += message_len; + memcpy(s, LIBSSH2_PUBLICKEY_STATUS_TEXT_END, sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END) - 1); + s += sizeof(LIBSSH2_PUBLICKEY_STATUS_TEXT_END); + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, m, 1); } /* }}} */ @@ -141,34 +141,34 @@ static void libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, LIBSSH */ static int libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data, unsigned long *data_len) { - LIBSSH2_CHANNEL *channel = pkey->channel; - LIBSSH2_SESSION *session = channel->session; - unsigned char buffer[4]; - unsigned long packet_len; - unsigned char *packet; + LIBSSH2_CHANNEL *channel = pkey->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned char buffer[4]; + unsigned long packet_len; + unsigned char *packet; - if (_libssh2_channel_read(channel, (char *)buffer, 4) != 4) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid response from publickey subsystem", 0); - return -1; - } + if (_libssh2_channel_read(channel, (char *)buffer, 4) != 4) { + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid response from publickey subsystem", 0); + return -1; + } - packet_len = libssh2_ntohu32(buffer); - packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate publickey response buffer", 0); - return -1; - } + packet_len = libssh2_ntohu32(buffer); + packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate publickey response buffer", 0); + return -1; + } - if (_libssh2_channel_read(channel, (char *)packet, packet_len) != packet_len) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for publickey subsystem response packet", 0); - LIBSSH2_FREE(session, packet); - return -1; - } + if (_libssh2_channel_read(channel, (char *)packet, packet_len) != packet_len) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for publickey subsystem response packet", 0); + LIBSSH2_FREE(session, packet); + return -1; + } - *data = packet; - *data_len = packet_len; + *data = packet; + *data_len = packet_len; - return 0; + return 0; } /* }}} */ @@ -178,30 +178,30 @@ static int libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned ch */ static int libssh2_publickey_response_id(unsigned char **pdata, int data_len) { - unsigned long response_len; - unsigned char *data = *pdata; - const LIBSSH2_PUBLICKEY_CODE_LIST *codes = libssh2_publickey_response_codes; + unsigned long response_len; + unsigned char *data = *pdata; + const LIBSSH2_PUBLICKEY_CODE_LIST *codes = libssh2_publickey_response_codes; - if (data_len < 4) { - /* Malformed response */ - return -1; - } - response_len = libssh2_ntohu32(data); data += 4; data_len -= 4; - if (data_len < response_len) { - /* Malformed response */ - return -1; - } + if (data_len < 4) { + /* Malformed response */ + return -1; + } + response_len = libssh2_ntohu32(data); data += 4; data_len -= 4; + if (data_len < response_len) { + /* Malformed response */ + return -1; + } - while (codes->name) { - if (codes->name_len == response_len && - strncmp(codes->name, (char *)data, response_len) == 0) { - *pdata = data + response_len; - return codes->code; - } - codes++; - } + while (codes->name) { + if (codes->name_len == response_len && + strncmp(codes->name, (char *)data, response_len) == 0) { + *pdata = data + response_len; + return codes->code; + } + codes++; + } - return -1; + return -1; } /* }}} */ @@ -210,61 +210,61 @@ static int libssh2_publickey_response_id(unsigned char **pdata, int data_len) */ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey) { - LIBSSH2_SESSION *session = pkey->channel->session; - unsigned char *data, *s; - unsigned long data_len; - int response; + LIBSSH2_SESSION *session = pkey->channel->session; + unsigned char *data, *s; + unsigned long data_len; + int response; - while (1) { - if (libssh2_publickey_packet_receive(pkey, &data, &data_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0); - return -1; - } + while (1) { + if (libssh2_publickey_packet_receive(pkey, &data, &data_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0); + return -1; + } - s = data; - if ((response = libssh2_publickey_response_id(&s, data_len)) < 0) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0); - LIBSSH2_FREE(session, data); - return -1; - } + s = data; + if ((response = libssh2_publickey_response_id(&s, data_len)) < 0) { + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0); + LIBSSH2_FREE(session, data); + return -1; + } - switch (response) { - case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: - /* Error, or processing complete */ - { - unsigned long status, descr_len, lang_len; - unsigned char *descr, *lang; - - status = libssh2_ntohu32(s); s += 4; - descr_len = libssh2_ntohu32(s); s += 4; - descr = s; s += descr_len; - lang_len = libssh2_ntohu32(s); s += 4; - lang = s; s += lang_len; + switch (response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error, or processing complete */ + { + unsigned long status, descr_len, lang_len; + unsigned char *descr, *lang; + + status = libssh2_ntohu32(s); s += 4; + descr_len = libssh2_ntohu32(s); s += 4; + descr = s; s += descr_len; + lang_len = libssh2_ntohu32(s); s += 4; + lang = s; s += lang_len; - if (s > data + data_len) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0); - LIBSSH2_FREE(session, data); - return -1; - } + if (s > data + data_len) { + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0); + LIBSSH2_FREE(session, data); + return -1; + } - if (status == LIBSSH2_PUBLICKEY_SUCCESS) { - LIBSSH2_FREE(session, data); - return 0; - } + if (status == LIBSSH2_PUBLICKEY_SUCCESS) { + LIBSSH2_FREE(session, data); + return 0; + } - libssh2_publickey_status_error(pkey, session, status, descr, descr_len); - LIBSSH2_FREE(session, data); - return -1; - } - default: - /* Unknown/Unexpected */ - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0); - LIBSSH2_FREE(session, data); - data = NULL; - } - } - /* never reached, but include `return` to silence compiler warnings */ - return -1; + libssh2_publickey_status_error(pkey, session, status, descr, descr_len); + LIBSSH2_FREE(session, data); + return -1; + } + default: + /* Unknown/Unexpected */ + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0); + LIBSSH2_FREE(session, data); + data = NULL; + } + } + /* never reached, but include `return` to silence compiler warnings */ + return -1; } /* }}} */ @@ -278,115 +278,115 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey) */ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session) { - LIBSSH2_PUBLICKEY *pkey = NULL; - LIBSSH2_CHANNEL *channel = NULL; - unsigned char buffer[19]; - /* packet_len(4) + - version_len(4) + - "version"(7) + - version_num(4) */ - unsigned char *s, *data = NULL; - unsigned long data_len; - int response; + LIBSSH2_PUBLICKEY *pkey = NULL; + LIBSSH2_CHANNEL *channel = NULL; + unsigned char buffer[19]; + /* packet_len(4) + + version_len(4) + + "version"(7) + + version_num(4) */ + unsigned char *s, *data = NULL; + unsigned long data_len; + int response; - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Initializing publickey subsystem"); + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Initializing publickey subsystem"); - channel = libssh2_channel_open_session(session); - if (!channel) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to startup channel", 0); - goto err_exit; - } - if (libssh2_channel_subsystem(channel, "publickey")) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to request publickey subsystem", 0); - goto err_exit; - } - - libssh2_channel_set_blocking(channel, 1); - libssh2_channel_handle_extended_data(channel, LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); - - pkey = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY)); - if (!pkey) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a new publickey structure", 0); - goto err_exit; - } - pkey->channel = channel; - pkey->version = 0; - - s = buffer; - libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4); s += 4; - libssh2_htonu32(s, sizeof("version") - 1); s += 4; - memcpy(s, "version", sizeof("version") - 1); s += sizeof("version") - 1; - libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); s += 4; - - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey version packet advertising version %d support", (int)LIBSSH2_PUBLICKEY_VERSION); - if ((s - buffer) != libssh2_channel_write(channel, (char*)buffer, (s - buffer))) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey version packet", 0); - goto err_exit; + channel = libssh2_channel_open_session(session); + if (!channel) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to startup channel", 0); + goto err_exit; + } + if (libssh2_channel_subsystem(channel, "publickey")) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to request publickey subsystem", 0); + goto err_exit; } - while (1) { - if (libssh2_publickey_packet_receive(pkey, &data, &data_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0); - goto err_exit; - } + libssh2_channel_set_blocking(channel, 1); + libssh2_channel_handle_extended_data(channel, LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); - s = data; - if ((response = libssh2_publickey_response_id(&s, data_len)) < 0) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0); - goto err_exit; - } + pkey = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY)); + if (!pkey) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a new publickey structure", 0); + goto err_exit; + } + pkey->channel = channel; + pkey->version = 0; - switch (response) { - case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: - /* Error */ - { - unsigned long status, descr_len, lang_len; - unsigned char *descr, *lang; - - status = libssh2_ntohu32(s); s += 4; - descr_len = libssh2_ntohu32(s); s += 4; - descr = s; s += descr_len; - lang_len = libssh2_ntohu32(s); s += 4; - lang = s; s += lang_len; + s = buffer; + libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4); s += 4; + libssh2_htonu32(s, sizeof("version") - 1); s += 4; + memcpy(s, "version", sizeof("version") - 1); s += sizeof("version") - 1; + libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); s += 4; - if (s > data + data_len) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0); - goto err_exit; - } + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey version packet advertising version %d support", (int)LIBSSH2_PUBLICKEY_VERSION); + if ((s - buffer) != libssh2_channel_write(channel, (char*)buffer, (s - buffer))) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey version packet", 0); + goto err_exit; + } - libssh2_publickey_status_error(NULL, session, status, descr, descr_len); - goto err_exit; - } - case LIBSSH2_PUBLICKEY_RESPONSE_VERSION: - /* What we want */ - pkey->version = libssh2_ntohu32(s); - if (pkey->version > LIBSSH2_PUBLICKEY_VERSION) { - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Truncating remote publickey version from %lu", pkey->version); - pkey->version = LIBSSH2_PUBLICKEY_VERSION; - } - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Enabling publickey subsystem version %lu", pkey->version); - LIBSSH2_FREE(session, data); - return pkey; - default: - /* Unknown/Unexpected */ - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0); - LIBSSH2_FREE(session, data); - data = NULL; - } - } + while (1) { + if (libssh2_publickey_packet_receive(pkey, &data, &data_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0); + goto err_exit; + } - /* Never reached except by direct goto */ + s = data; + if ((response = libssh2_publickey_response_id(&s, data_len)) < 0) { + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0); + goto err_exit; + } + + switch (response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error */ + { + unsigned long status, descr_len, lang_len; + unsigned char *descr, *lang; + + status = libssh2_ntohu32(s); s += 4; + descr_len = libssh2_ntohu32(s); s += 4; + descr = s; s += descr_len; + lang_len = libssh2_ntohu32(s); s += 4; + lang = s; s += lang_len; + + if (s > data + data_len) { + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0); + goto err_exit; + } + + libssh2_publickey_status_error(NULL, session, status, descr, descr_len); + goto err_exit; + } + case LIBSSH2_PUBLICKEY_RESPONSE_VERSION: + /* What we want */ + pkey->version = libssh2_ntohu32(s); + if (pkey->version > LIBSSH2_PUBLICKEY_VERSION) { + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Truncating remote publickey version from %lu", pkey->version); + pkey->version = LIBSSH2_PUBLICKEY_VERSION; + } + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Enabling publickey subsystem version %lu", pkey->version); + LIBSSH2_FREE(session, data); + return pkey; + default: + /* Unknown/Unexpected */ + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0); + LIBSSH2_FREE(session, data); + data = NULL; + } + } + + /* Never reached except by direct goto */ err_exit: - if (channel) { - libssh2_channel_close(channel); - } - if (pkey) { - LIBSSH2_FREE(session, pkey); - } - if (data) { - LIBSSH2_FREE(session, data); - } - return NULL; + if (channel) { + libssh2_channel_close(channel); + } + if (pkey) { + LIBSSH2_FREE(session, pkey); + } + if (data) { + LIBSSH2_FREE(session, data); + } + return NULL; } /* }}} */ @@ -394,94 +394,94 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session) * Add a new public key entry */ LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, - const unsigned char *blob, unsigned long blob_len, char overwrite, - unsigned long num_attrs, const libssh2_publickey_attribute attrs[]) + const unsigned char *blob, unsigned long blob_len, char overwrite, + unsigned long num_attrs, const libssh2_publickey_attribute attrs[]) { - LIBSSH2_CHANNEL *channel = pkey->channel; - LIBSSH2_SESSION *session = channel->session; - unsigned char *packet = NULL, *s; - unsigned long i, packet_len = 19 + name_len + blob_len; - unsigned char *comment = NULL; - unsigned long comment_len = 0; - /* packet_len(4) + - add_len(4) + - "add"(3) + - name_len(4) + - {name} - blob_len(4) + - {blob} */ + LIBSSH2_CHANNEL *channel = pkey->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned char *packet = NULL, *s; + unsigned long i, packet_len = 19 + name_len + blob_len; + unsigned char *comment = NULL; + unsigned long comment_len = 0; + /* packet_len(4) + + add_len(4) + + "add"(3) + + name_len(4) + + {name} + blob_len(4) + + {blob} */ - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s pubickey", name); + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s pubickey", name); - if (pkey->version == 1) { - for(i = 0; i < num_attrs; i++) { - /* Search for a comment attribute */ - if (attrs[i].name_len == (sizeof("comment") - 1) && - strncmp(attrs[i].name, "comment", sizeof("comment") - 1) == 0) { - comment = (unsigned char *)attrs[i].value; - comment_len = attrs[i].value_len; - break; - } - } - packet_len += 4 + comment_len; - } else { - packet_len += 5; /* overwrite(1) + attribute_count(4) */ - for(i = 0; i < num_attrs; i++) { - packet_len += 9 + attrs[i].name_len + attrs[i].value_len; - /* name_len(4) + value_len(4) + mandatory(1) */ - } - } + if (pkey->version == 1) { + for(i = 0; i < num_attrs; i++) { + /* Search for a comment attribute */ + if (attrs[i].name_len == (sizeof("comment") - 1) && + strncmp(attrs[i].name, "comment", sizeof("comment") - 1) == 0) { + comment = (unsigned char *)attrs[i].value; + comment_len = attrs[i].value_len; + break; + } + } + packet_len += 4 + comment_len; + } else { + packet_len += 5; /* overwrite(1) + attribute_count(4) */ + for(i = 0; i < num_attrs; i++) { + packet_len += 9 + attrs[i].name_len + attrs[i].value_len; + /* name_len(4) + value_len(4) + mandatory(1) */ + } + } - packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey \"add\" packet", 0); - return -1; - } + packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey \"add\" packet", 0); + return -1; + } - s = packet; - libssh2_htonu32(s, packet_len - 4); s += 4; - libssh2_htonu32(s, sizeof("add") - 1); s += 4; - memcpy(s, "add", sizeof("add") - 1); s += sizeof("add") - 1; - if (pkey->version == 1) { - libssh2_htonu32(s, comment_len); s += 4; - if (comment) { - memcpy(s, comment, comment_len); s += comment_len; - } + s = packet; + libssh2_htonu32(s, packet_len - 4); s += 4; + libssh2_htonu32(s, sizeof("add") - 1); s += 4; + memcpy(s, "add", sizeof("add") - 1); s += sizeof("add") - 1; + if (pkey->version == 1) { + libssh2_htonu32(s, comment_len); s += 4; + if (comment) { + memcpy(s, comment, comment_len); s += comment_len; + } - libssh2_htonu32(s, name_len); s += 4; - memcpy(s, name, name_len); s += name_len; - libssh2_htonu32(s, blob_len); s += 4; - memcpy(s, blob, blob_len); s += blob_len; - } else { - /* Version == 2 */ + libssh2_htonu32(s, name_len); s += 4; + memcpy(s, name, name_len); s += name_len; + libssh2_htonu32(s, blob_len); s += 4; + memcpy(s, blob, blob_len); s += blob_len; + } else { + /* Version == 2 */ - libssh2_htonu32(s, name_len); s += 4; - memcpy(s, name, name_len); s += name_len; - libssh2_htonu32(s, blob_len); s += 4; - memcpy(s, blob, blob_len); s += blob_len; - *(s++) = overwrite ? 0xFF : 0; - libssh2_htonu32(s, num_attrs); s += 4; - for(i = 0; i < num_attrs; i++) { - libssh2_htonu32(s, attrs[i].name_len); s += 4; - memcpy(s, attrs[i].name, attrs[i].name_len); s += attrs[i].name_len; - libssh2_htonu32(s, attrs[i].value_len); s += 4; - memcpy(s, attrs[i].value, attrs[i].value_len); s += attrs[i].value_len; - *(s++) = attrs[i].mandatory ? 0xFF : 0; - } - } + libssh2_htonu32(s, name_len); s += 4; + memcpy(s, name, name_len); s += name_len; + libssh2_htonu32(s, blob_len); s += 4; + memcpy(s, blob, blob_len); s += blob_len; + *(s++) = overwrite ? 0xFF : 0; + libssh2_htonu32(s, num_attrs); s += 4; + for(i = 0; i < num_attrs; i++) { + libssh2_htonu32(s, attrs[i].name_len); s += 4; + memcpy(s, attrs[i].name, attrs[i].name_len); s += attrs[i].name_len; + libssh2_htonu32(s, attrs[i].value_len); s += 4; + memcpy(s, attrs[i].value, attrs[i].value_len); s += attrs[i].value_len; + *(s++) = attrs[i].mandatory ? 0xFF : 0; + } + } - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, - "Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld", - name, blob_len, num_attrs); + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, + "Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld", + name, blob_len, num_attrs); if ((s - packet) != libssh2_channel_write(channel, (char *)packet, (s - packet))) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey add packet", 0); - LIBSSH2_FREE(session, packet); - return -1; + LIBSSH2_FREE(session, packet); + return -1; } - LIBSSH2_FREE(session, packet); - packet = NULL; + LIBSSH2_FREE(session, packet); + packet = NULL; - return libssh2_publickey_response_success(pkey); + return libssh2_publickey_response_success(pkey); } /* }}} */ @@ -491,43 +491,43 @@ LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, const unsigned char *blob, unsigned long blob_len) { - LIBSSH2_CHANNEL *channel = pkey->channel; - LIBSSH2_SESSION *session = channel->session; - unsigned char *s, *packet = NULL; - unsigned long packet_len = 22 + name_len + blob_len; - /* packet_len(4) + - remove_len(4) + - "remove"(6) + - name_len(4) + - {name} - blob_len(4) + - {blob} */ + LIBSSH2_CHANNEL *channel = pkey->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned char *s, *packet = NULL; + unsigned long packet_len = 22 + name_len + blob_len; + /* packet_len(4) + + remove_len(4) + + "remove"(6) + + name_len(4) + + {name} + blob_len(4) + + {blob} */ - packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey \"remove\" packet", 0); - return -1; - } + packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey \"remove\" packet", 0); + return -1; + } - s = packet; - libssh2_htonu32(s, packet_len - 4); s += 4; - libssh2_htonu32(s, sizeof("remove") - 1); s += 4; - memcpy(s, "remove", sizeof("remove") - 1); s += sizeof("remove") - 1; - libssh2_htonu32(s, name_len); s += 4; - memcpy(s, name, name_len); s += name_len; - libssh2_htonu32(s, blob_len); s += 4; - memcpy(s, blob, blob_len); s += blob_len; + s = packet; + libssh2_htonu32(s, packet_len - 4); s += 4; + libssh2_htonu32(s, sizeof("remove") - 1); s += 4; + memcpy(s, "remove", sizeof("remove") - 1); s += sizeof("remove") - 1; + libssh2_htonu32(s, name_len); s += 4; + memcpy(s, name, name_len); s += name_len; + libssh2_htonu32(s, blob_len); s += 4; + memcpy(s, blob, blob_len); s += blob_len; - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"remove\" packet: type=%s blob_len=%ld", name, blob_len); - if ((s - packet) != libssh2_channel_write(channel, (char *)packet, (s - packet))) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey remove packet", 0); - LIBSSH2_FREE(session, packet); - return -1; - } - LIBSSH2_FREE(session, packet); - packet = NULL; + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"remove\" packet: type=%s blob_len=%ld", name, blob_len); + if ((s - packet) != libssh2_channel_write(channel, (char *)packet, (s - packet))) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey remove packet", 0); + LIBSSH2_FREE(session, packet); + return -1; + } + LIBSSH2_FREE(session, packet); + packet = NULL; - return libssh2_publickey_response_success(pkey); + return libssh2_publickey_response_success(pkey); } /* }}} */ @@ -536,152 +536,152 @@ LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsig */ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, libssh2_publickey_list **pkey_list) { - LIBSSH2_CHANNEL *channel = pkey->channel; - LIBSSH2_SESSION *session = channel->session; - libssh2_publickey_list *list = NULL; - unsigned char *s, buffer[12], *data = NULL; - unsigned long buffer_len = 12, keys = 0, max_keys = 0, data_len, i; - /* packet_len(4) + - list_len(4) + - "list"(4) */ - int response; + LIBSSH2_CHANNEL *channel = pkey->channel; + LIBSSH2_SESSION *session = channel->session; + libssh2_publickey_list *list = NULL; + unsigned char *s, buffer[12], *data = NULL; + unsigned long buffer_len = 12, keys = 0, max_keys = 0, data_len, i; + /* packet_len(4) + + list_len(4) + + "list"(4) */ + int response; - s = buffer; - libssh2_htonu32(s, buffer_len - 4); s += 4; - libssh2_htonu32(s, sizeof("list") - 1); s += 4; - memcpy(s, "list", sizeof("list") - 1); s += sizeof("list") - 1; + s = buffer; + libssh2_htonu32(s, buffer_len - 4); s += 4; + libssh2_htonu32(s, sizeof("list") - 1); s += 4; + memcpy(s, "list", sizeof("list") - 1); s += sizeof("list") - 1; - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"list\" packet"); - if ((s - buffer) != libssh2_channel_write(channel, (char *)buffer, (s - buffer))) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey list packet", 0); - return -1; - } + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"list\" packet"); + if ((s - buffer) != libssh2_channel_write(channel, (char *)buffer, (s - buffer))) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey list packet", 0); + return -1; + } - while (1) { - if (libssh2_publickey_packet_receive(pkey, &data, &data_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0); - goto err_exit; - } + while (1) { + if (libssh2_publickey_packet_receive(pkey, &data, &data_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0); + goto err_exit; + } - s = data; - if ((response = libssh2_publickey_response_id(&s, data_len)) < 0) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0); - goto err_exit; - } + s = data; + if ((response = libssh2_publickey_response_id(&s, data_len)) < 0) { + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0); + goto err_exit; + } - switch (response) { - case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: - /* Error, or processing complete */ - { - unsigned long status, descr_len, lang_len; - unsigned char *descr, *lang; - - status = libssh2_ntohu32(s); s += 4; - descr_len = libssh2_ntohu32(s); s += 4; - descr = s; s += descr_len; - lang_len = libssh2_ntohu32(s); s += 4; - lang = s; s += lang_len; + switch (response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error, or processing complete */ + { + unsigned long status, descr_len, lang_len; + unsigned char *descr, *lang; + + status = libssh2_ntohu32(s); s += 4; + descr_len = libssh2_ntohu32(s); s += 4; + descr = s; s += descr_len; + lang_len = libssh2_ntohu32(s); s += 4; + lang = s; s += lang_len; - if (s > data + data_len) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0); - goto err_exit; - } + if (s > data + data_len) { + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0); + goto err_exit; + } - if (status == LIBSSH2_PUBLICKEY_SUCCESS) { - LIBSSH2_FREE(session, data); - *pkey_list = list; - *num_keys = keys; - return 0; - } + if (status == LIBSSH2_PUBLICKEY_SUCCESS) { + LIBSSH2_FREE(session, data); + *pkey_list = list; + *num_keys = keys; + return 0; + } - libssh2_publickey_status_error(pkey, session, status, descr, descr_len); - goto err_exit; - } - case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY: - /* What we want */ - if (keys >= max_keys) { - libssh2_publickey_list *newlist; - /* Grow the key list if necessary */ - max_keys += 8; - newlist = LIBSSH2_REALLOC(session, list, (max_keys + 1) * sizeof(libssh2_publickey_list)); - if (!newlist) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey list", 0); - goto err_exit; - } - list = newlist; - } - if (pkey->version == 1) { - unsigned long comment_len; + libssh2_publickey_status_error(pkey, session, status, descr, descr_len); + goto err_exit; + } + case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY: + /* What we want */ + if (keys >= max_keys) { + libssh2_publickey_list *newlist; + /* Grow the key list if necessary */ + max_keys += 8; + newlist = LIBSSH2_REALLOC(session, list, (max_keys + 1) * sizeof(libssh2_publickey_list)); + if (!newlist) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey list", 0); + goto err_exit; + } + list = newlist; + } + if (pkey->version == 1) { + unsigned long comment_len; - comment_len = libssh2_ntohu32(s); s += 4; - if (comment_len) { - list[keys].num_attrs = 1; - list[keys].attrs = LIBSSH2_ALLOC(session, sizeof(libssh2_publickey_attribute)); - if (!list[keys].attrs) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey attributes", 0); - goto err_exit; - } - list[keys].attrs[0].name = "comment"; - list[keys].attrs[0].name_len = sizeof("comment") - 1; - list[keys].attrs[0].value = (char *)s; - list[keys].attrs[0].value_len = comment_len; - list[keys].attrs[0].mandatory = 0; + comment_len = libssh2_ntohu32(s); s += 4; + if (comment_len) { + list[keys].num_attrs = 1; + list[keys].attrs = LIBSSH2_ALLOC(session, sizeof(libssh2_publickey_attribute)); + if (!list[keys].attrs) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey attributes", 0); + goto err_exit; + } + list[keys].attrs[0].name = "comment"; + list[keys].attrs[0].name_len = sizeof("comment") - 1; + list[keys].attrs[0].value = (char *)s; + list[keys].attrs[0].value_len = comment_len; + list[keys].attrs[0].mandatory = 0; - s += comment_len; - } else { - list[keys].num_attrs = 0; - list[keys].attrs = NULL; - } - list[keys].name_len = libssh2_ntohu32(s); s += 4; - list[keys].name = s; s += list[keys].name_len; - list[keys].blob_len = libssh2_ntohu32(s); s += 4; - list[keys].blob = s; s += list[keys].blob_len; - } else { - /* Version == 2 */ - list[keys].name_len = libssh2_ntohu32(s); s += 4; - list[keys].name = s; s += list[keys].name_len; - list[keys].blob_len = libssh2_ntohu32(s); s += 4; - list[keys].blob = s; s += list[keys].blob_len; - list[keys].num_attrs = libssh2_ntohu32(s); s += 4; - if (list[keys].num_attrs) { - list[keys].attrs = LIBSSH2_ALLOC(session, list[keys].num_attrs * sizeof(libssh2_publickey_attribute)); - if (!list[keys].attrs) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey attributes", 0); - goto err_exit; - } - for(i = 0; i < list[keys].num_attrs; i++) { - list[keys].attrs[i].name_len = libssh2_ntohu32(s); s += 4; - list[keys].attrs[i].name = (char *)s; s += list[keys].attrs[i].name_len; - list[keys].attrs[i].value_len = libssh2_ntohu32(s); s += 4; - list[keys].attrs[i].value = (char *)s; s += list[keys].attrs[i].value_len; - list[keys].attrs[i].mandatory = 0; /* actually an ignored value */ - } - } else { - list[keys].attrs = NULL; - } - } - list[keys].packet = data; /* To be FREEd in libssh2_publickey_list_free() */ - keys++; + s += comment_len; + } else { + list[keys].num_attrs = 0; + list[keys].attrs = NULL; + } + list[keys].name_len = libssh2_ntohu32(s); s += 4; + list[keys].name = s; s += list[keys].name_len; + list[keys].blob_len = libssh2_ntohu32(s); s += 4; + list[keys].blob = s; s += list[keys].blob_len; + } else { + /* Version == 2 */ + list[keys].name_len = libssh2_ntohu32(s); s += 4; + list[keys].name = s; s += list[keys].name_len; + list[keys].blob_len = libssh2_ntohu32(s); s += 4; + list[keys].blob = s; s += list[keys].blob_len; + list[keys].num_attrs = libssh2_ntohu32(s); s += 4; + if (list[keys].num_attrs) { + list[keys].attrs = LIBSSH2_ALLOC(session, list[keys].num_attrs * sizeof(libssh2_publickey_attribute)); + if (!list[keys].attrs) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey attributes", 0); + goto err_exit; + } + for(i = 0; i < list[keys].num_attrs; i++) { + list[keys].attrs[i].name_len = libssh2_ntohu32(s); s += 4; + list[keys].attrs[i].name = (char *)s; s += list[keys].attrs[i].name_len; + list[keys].attrs[i].value_len = libssh2_ntohu32(s); s += 4; + list[keys].attrs[i].value = (char *)s; s += list[keys].attrs[i].value_len; + list[keys].attrs[i].mandatory = 0; /* actually an ignored value */ + } + } else { + list[keys].attrs = NULL; + } + } + list[keys].packet = data; /* To be FREEd in libssh2_publickey_list_free() */ + keys++; - list[keys].packet = NULL; /* Terminate the list */ - data = NULL; - break; - default: - /* Unknown/Unexpected */ - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0); - LIBSSH2_FREE(session, data); - } - } + list[keys].packet = NULL; /* Terminate the list */ + data = NULL; + break; + default: + /* Unknown/Unexpected */ + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0); + LIBSSH2_FREE(session, data); + } + } - /* Only reached via explicit goto */ + /* Only reached via explicit goto */ err_exit: - if (data) { - LIBSSH2_FREE(session, data); - } - if (list) { - libssh2_publickey_list_free(pkey, list); - } - return -1; + if (data) { + LIBSSH2_FREE(session, data); + } + if (list) { + libssh2_publickey_list_free(pkey, list); + } + return -1; } /* }}} */ @@ -690,18 +690,18 @@ LIBSSH2_API int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned l */ LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_publickey_list *pkey_list) { - LIBSSH2_SESSION *session = pkey->channel->session; - libssh2_publickey_list *p = pkey_list; + LIBSSH2_SESSION *session = pkey->channel->session; + libssh2_publickey_list *p = pkey_list; - while (p->packet) { - if (p->attrs) { - LIBSSH2_FREE(session, p->attrs); - } - LIBSSH2_FREE(session, p->packet); - p++; - } + while (p->packet) { + if (p->attrs) { + LIBSSH2_FREE(session, p->attrs); + } + LIBSSH2_FREE(session, p->packet); + p++; + } - LIBSSH2_FREE(session, pkey_list); + LIBSSH2_FREE(session, pkey_list); } /* }}} */ @@ -710,9 +710,9 @@ LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_pu */ LIBSSH2_API void libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey) { - LIBSSH2_SESSION *session = pkey->channel->session; + LIBSSH2_SESSION *session = pkey->channel->session; - libssh2_channel_free(pkey->channel); - LIBSSH2_FREE(session, pkey); + libssh2_channel_free(pkey->channel); + LIBSSH2_FREE(session, pkey); } /* }}} */ diff --git a/src/scp.c b/src/scp.c index 1046cd0..112bf2d 100644 --- a/src/scp.c +++ b/src/scp.c @@ -39,289 +39,289 @@ #include #include -#define LIBSSH2_SCP_RESPONSE_BUFLEN 256 +#define LIBSSH2_SCP_RESPONSE_BUFLEN 256 /* {{{ libssh2_scp_recv * [BLOCKING] * Open a channel and request a remote file via SCP */ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, - const char *path, - struct stat *sb) + const char *path, + struct stat *sb) { - int path_len = strlen(path); - unsigned char *command, response[LIBSSH2_SCP_RESPONSE_BUFLEN]; - unsigned long command_len = path_len + sizeof("scp -f "), response_len; - LIBSSH2_CHANNEL *channel; - long mode = 0, size = 0, mtime = 0, atime = 0; + int path_len = strlen(path); + unsigned char *command, response[LIBSSH2_SCP_RESPONSE_BUFLEN]; + unsigned long command_len = path_len + sizeof("scp -f "), response_len; + LIBSSH2_CHANNEL *channel; + long mode = 0, size = 0, mtime = 0, atime = 0; - if (sb) { - command_len++; - } + if (sb) { + command_len++; + } - command = LIBSSH2_ALLOC(session, command_len); - if (!command) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0); - return NULL; - } - if (sb) { - memcpy(command, "scp -pf ", sizeof("scp -pf ") - 1); - memcpy(command + sizeof("scp -pf ") - 1, path, path_len); - } else { - memcpy(command, "scp -f ", sizeof("scp -f ") - 1); - memcpy(command + sizeof("scp -f ") - 1, path, path_len); - } - command[command_len - 1] = '\0'; + command = LIBSSH2_ALLOC(session, command_len); + if (!command) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0); + return NULL; + } + if (sb) { + memcpy(command, "scp -pf ", sizeof("scp -pf ") - 1); + memcpy(command + sizeof("scp -pf ") - 1, path, path_len); + } else { + memcpy(command, "scp -f ", sizeof("scp -f ") - 1); + memcpy(command + sizeof("scp -f ") - 1, path, path_len); + } + command[command_len - 1] = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive"); - /* Allocate a channel */ - if ((channel = libssh2_channel_open_session(session)) == NULL) { - LIBSSH2_FREE(session, command); - return NULL; - } - /* Use blocking I/O for negotiation phase */ - libssh2_channel_set_blocking(channel, 1); + _libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive"); + /* Allocate a channel */ + if ((channel = libssh2_channel_open_session(session)) == NULL) { + LIBSSH2_FREE(session, command); + return NULL; + } + /* Use blocking I/O for negotiation phase */ + libssh2_channel_set_blocking(channel, 1); - /* Request SCP for the desired file */ - if (libssh2_channel_process_startup(channel, "exec", sizeof("exec") - 1, command, command_len)) { - LIBSSH2_FREE(session, command); - libssh2_channel_free(channel); - return NULL; - } - LIBSSH2_FREE(session, command); + /* Request SCP for the desired file */ + if (libssh2_channel_process_startup(channel, "exec", sizeof("exec") - 1, command, command_len)) { + LIBSSH2_FREE(session, command); + libssh2_channel_free(channel); + return NULL; + } + LIBSSH2_FREE(session, command); - _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup"); - /* SCP ACK */ - response[0] = '\0'; - if (libssh2_channel_write(channel, response, 1) != 1) { - libssh2_channel_free(channel); - return NULL; - } + _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup"); + /* SCP ACK */ + response[0] = '\0'; + if (libssh2_channel_write(channel, response, 1) != 1) { + libssh2_channel_free(channel); + return NULL; + } - /* Parse SCP response */ - response_len = 0; - while (sb && (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) { - unsigned char *s, *p; - int rc; + /* Parse SCP response */ + response_len = 0; + while (sb && (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) { + unsigned char *s, *p; + int rc; - rc = _libssh2_channel_read(channel, response + response_len, 1); - if(rc <= 0) { - /* Timeout, give up */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0); - libssh2_channel_free(channel); - return NULL; - } - response_len++; + rc = _libssh2_channel_read(channel, response + response_len, 1); + if(rc <= 0) { + /* Timeout, give up */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0); + libssh2_channel_free(channel); + return NULL; + } + response_len++; - if (response[0] != 'T') { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response, missing Time data", 0); - libssh2_channel_free(channel); - return NULL; - } + if (response[0] != 'T') { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response, missing Time data", 0); + libssh2_channel_free(channel); + return NULL; + } - if ((response_len > 1) && - ((response[response_len-1] < '0') || (response[response_len-1] > '9')) && - (response[response_len-1] != ' ') && - (response[response_len-1] != '\r') && - (response[response_len-1] != '\n')) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); - libssh2_channel_free(channel); - return NULL; - } + if ((response_len > 1) && + ((response[response_len-1] < '0') || (response[response_len-1] > '9')) && + (response[response_len-1] != ' ') && + (response[response_len-1] != '\r') && + (response[response_len-1] != '\n')) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); + libssh2_channel_free(channel); + return NULL; + } - if ((response_len < 9) || (response[response_len-1] != '\n')) { - if (response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { - /* You had your chance */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0); - libssh2_channel_free(channel); - return NULL; - } - /* Way too short to be an SCP response, or not done yet, short circuit */ - continue; - } + if ((response_len < 9) || (response[response_len-1] != '\n')) { + if (response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { + /* You had your chance */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0); + libssh2_channel_free(channel); + return NULL; + } + /* Way too short to be an SCP response, or not done yet, short circuit */ + continue; + } - /* We're guaranteed not to go under response_len == 0 by the logic above */ - while ((response[response_len-1] == '\r') || (response[response_len-1] == '\n')) response_len--; - response[response_len] = '\0'; + /* We're guaranteed not to go under response_len == 0 by the logic above */ + while ((response[response_len-1] == '\r') || (response[response_len-1] == '\n')) response_len--; + response[response_len] = '\0'; - if (response_len < 8) { - /* EOL came too soon */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0); - libssh2_channel_free(channel); - return NULL; - } + if (response_len < 8) { + /* EOL came too soon */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0); + libssh2_channel_free(channel); + return NULL; + } - s = response + 1; + s = response + 1; - p = strchr(s, ' '); - if (!p || ((p - s) <= 0)) { - /* No spaces or space in the wrong spot */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime", 0); - libssh2_channel_free(channel); - return NULL; - } + p = strchr(s, ' '); + if (!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime", 0); + libssh2_channel_free(channel); + return NULL; + } - *(p++) = '\0'; - /* Make sure we don't get fooled by leftover values */ - errno = 0; - mtime = strtol(s, NULL, 10); - if (errno) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mtime", 0); - libssh2_channel_free(channel); - return NULL; - } - s = strchr(p, ' '); - if (!s || ((s - p) <= 0)) { - /* No spaces or space in the wrong spot */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime.usec", 0); - libssh2_channel_free(channel); - return NULL; - } + *(p++) = '\0'; + /* Make sure we don't get fooled by leftover values */ + errno = 0; + mtime = strtol(s, NULL, 10); + if (errno) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mtime", 0); + libssh2_channel_free(channel); + return NULL; + } + s = strchr(p, ' '); + if (!s || ((s - p) <= 0)) { + /* No spaces or space in the wrong spot */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mtime.usec", 0); + libssh2_channel_free(channel); + return NULL; + } - /* Ignore mtime.usec */ - s++; - p = strchr(s, ' '); - if (!p || ((p - s) <= 0)) { - /* No spaces or space in the wrong spot */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0); - libssh2_channel_free(channel); - return NULL; - } + /* Ignore mtime.usec */ + s++; + p = strchr(s, ' '); + if (!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0); + libssh2_channel_free(channel); + return NULL; + } - *(p++) = '\0'; - /* Make sure we don't get fooled by leftover values */ - errno = 0; - atime = strtol(s, NULL, 10); - if (errno) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid atime", 0); - libssh2_channel_free(channel); - return NULL; - } + *(p++) = '\0'; + /* Make sure we don't get fooled by leftover values */ + errno = 0; + atime = strtol(s, NULL, 10); + if (errno) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid atime", 0); + libssh2_channel_free(channel); + return NULL; + } - /* SCP ACK */ - response[0] = '\0'; - if (libssh2_channel_write(channel, response, 1) != 1) { - libssh2_channel_free(channel); - return NULL; - } + /* SCP ACK */ + response[0] = '\0'; + if (libssh2_channel_write(channel, response, 1) != 1) { + libssh2_channel_free(channel); + return NULL; + } - _libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", mtime, atime); + _libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", mtime, atime); - /* We *should* check that atime.usec is valid, but why let that stop use? */ - break; - } + /* We *should* check that atime.usec is valid, but why let that stop use? */ + break; + } - response_len = 0; - while (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { - char *s, *p, *e = NULL; + response_len = 0; + while (response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { + char *s, *p, *e = NULL; - if (_libssh2_channel_read(channel, response + response_len, 1) <= 0) { - /* Timeout, give up */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0); - libssh2_channel_free(channel); - return NULL; - } - response_len++; + if (_libssh2_channel_read(channel, response + response_len, 1) <= 0) { + /* Timeout, give up */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0); + libssh2_channel_free(channel); + return NULL; + } + response_len++; - if (response[0] != 'C') { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server", 0); - libssh2_channel_free(channel); - return NULL; - } + if (response[0] != 'C') { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server", 0); + libssh2_channel_free(channel); + return NULL; + } - if ((response_len > 1) && - (response[response_len-1] != '\r') && - (response[response_len-1] != '\n') && - ((response[response_len-1] < 32) || (response[response_len-1] > 126))) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); - libssh2_channel_free(channel); - return NULL; - } + if ((response_len > 1) && + (response[response_len-1] != '\r') && + (response[response_len-1] != '\n') && + ((response[response_len-1] < 32) || (response[response_len-1] > 126))) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); + libssh2_channel_free(channel); + return NULL; + } - if ((response_len < 7) || (response[response_len-1] != '\n')) { - if (response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { - /* You had your chance */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0); - libssh2_channel_free(channel); - return NULL; - } - /* Way too short to be an SCP response, or not done yet, short circuit */ - continue; - } + if ((response_len < 7) || (response[response_len-1] != '\n')) { + if (response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { + /* You had your chance */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0); + libssh2_channel_free(channel); + return NULL; + } + /* Way too short to be an SCP response, or not done yet, short circuit */ + continue; + } - /* We're guaranteed not to go under response_len == 0 by the logic above */ - while ((response[response_len-1] == '\r') || (response[response_len-1] == '\n')) response_len--; - response[response_len] = '\0'; + /* We're guaranteed not to go under response_len == 0 by the logic above */ + while ((response[response_len-1] == '\r') || (response[response_len-1] == '\n')) response_len--; + response[response_len] = '\0'; - if (response_len < 6) { - /* EOL came too soon */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0); - libssh2_channel_free(channel); - return NULL; - } + if (response_len < 6) { + /* EOL came too soon */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0); + libssh2_channel_free(channel); + return NULL; + } - s = response + 1; + s = response + 1; - p = strchr(s, ' '); - if (!p || ((p - s) <= 0)) { - /* No spaces or space in the wrong spot */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mode", 0); - libssh2_channel_free(channel); - return NULL; - } + p = strchr(s, ' '); + if (!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, malformed mode", 0); + libssh2_channel_free(channel); + return NULL; + } - *(p++) = '\0'; - /* Make sure we don't get fooled by leftover values */ - errno = 0; - mode = strtol(s, &e, 8); - if ((e && *e) || errno) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mode", 0); - libssh2_channel_free(channel); - return NULL; - } + *(p++) = '\0'; + /* Make sure we don't get fooled by leftover values */ + errno = 0; + mode = strtol(s, &e, 8); + if ((e && *e) || errno) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mode", 0); + libssh2_channel_free(channel); + return NULL; + } - s = strchr(p, ' '); - if (!s || ((s - p) <= 0)) { - /* No spaces or space in the wrong spot */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0); - libssh2_channel_free(channel); - return NULL; - } + s = strchr(p, ' '); + if (!s || ((s - p) <= 0)) { + /* No spaces or space in the wrong spot */ + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short or malformed", 0); + libssh2_channel_free(channel); + return NULL; + } - *(s++) = '\0'; - /* Make sure we don't get fooled by leftover values */ - errno = 0; - size = strtol(p, &e, 10); - if ((e && *e) || errno) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid size", 0); - libssh2_channel_free(channel); - return NULL; - } + *(s++) = '\0'; + /* Make sure we don't get fooled by leftover values */ + errno = 0; + size = strtol(p, &e, 10); + if ((e && *e) || errno) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid size", 0); + libssh2_channel_free(channel); + return NULL; + } - /* SCP ACK */ - response[0] = '\0'; - if (libssh2_channel_write(channel, response, 1) != 1) { - libssh2_channel_free(channel); - return NULL; - } - _libssh2_debug(session, LIBSSH2_DBG_SCP, "mod = 0%lo size = %ld", mode, size); + /* SCP ACK */ + response[0] = '\0'; + if (libssh2_channel_write(channel, response, 1) != 1) { + libssh2_channel_free(channel); + return NULL; + } + _libssh2_debug(session, LIBSSH2_DBG_SCP, "mod = 0%lo size = %ld", mode, size); - /* We *should* check that basename is valid, but why let that stop us? */ - break; - } + /* We *should* check that basename is valid, but why let that stop us? */ + break; + } - if (sb) { - memset(sb, 0, sizeof(struct stat)); + if (sb) { + memset(sb, 0, sizeof(struct stat)); - sb->st_mtime = mtime; - sb->st_atime = atime; - sb->st_size = size; - sb->st_mode = mode; - } - /* Revert to non-blocking and let the data BEGIN! */ - libssh2_channel_set_blocking(channel, 0); + sb->st_mtime = mtime; + sb->st_atime = atime; + sb->st_size = size; + sb->st_mode = mode; + } + /* Revert to non-blocking and let the data BEGIN! */ + libssh2_channel_set_blocking(channel, 0); - return channel; + return channel; } /* }}} */ @@ -330,101 +330,101 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, */ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime) { - int path_len = strlen(path); - unsigned char *command, response[LIBSSH2_SCP_RESPONSE_BUFLEN]; - unsigned long response_len, command_len = path_len + sizeof("scp -t "); - unsigned const char *base; - LIBSSH2_CHANNEL *channel; + int path_len = strlen(path); + unsigned char *command, response[LIBSSH2_SCP_RESPONSE_BUFLEN]; + unsigned long response_len, command_len = path_len + sizeof("scp -t "); + unsigned const char *base; + LIBSSH2_CHANNEL *channel; - if (mtime || atime) { - command_len++; - } + if (mtime || atime) { + command_len++; + } - command = LIBSSH2_ALLOC(session, command_len); - if (!command) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0); - return NULL; - } + command = LIBSSH2_ALLOC(session, command_len); + if (!command) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0); + return NULL; + } - if (mtime || atime) { - memcpy(command, "scp -pt ", sizeof("scp -pt ") - 1); - memcpy(command + sizeof("scp -pt ") - 1, path, path_len); - } else { - memcpy(command, "scp -t ", sizeof("scp -t ") - 1); - memcpy(command + sizeof("scp -t ") - 1, path, path_len); - } - command[command_len - 1] = '\0'; + if (mtime || atime) { + memcpy(command, "scp -pt ", sizeof("scp -pt ") - 1); + memcpy(command + sizeof("scp -pt ") - 1, path, path_len); + } else { + memcpy(command, "scp -t ", sizeof("scp -t ") - 1); + memcpy(command + sizeof("scp -t ") - 1, path, path_len); + } + command[command_len - 1] = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send"); - /* Allocate a channel */ - if ((channel = libssh2_channel_open_session(session)) == NULL) { - /* previous call set libssh2_session_last_error(), pass it through */ - LIBSSH2_FREE(session, command); - return NULL; - } - /* Use blocking I/O for negotiation phase */ - libssh2_channel_set_blocking(channel, 1); + _libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send"); + /* Allocate a channel */ + if ((channel = libssh2_channel_open_session(session)) == NULL) { + /* previous call set libssh2_session_last_error(), pass it through */ + LIBSSH2_FREE(session, command); + return NULL; + } + /* Use blocking I/O for negotiation phase */ + libssh2_channel_set_blocking(channel, 1); - /* Request SCP for the desired file */ - if (libssh2_channel_process_startup(channel, "exec", sizeof("exec") - 1, command, command_len)) { - /* previous call set libssh2_session_last_error(), pass it through */ - LIBSSH2_FREE(session, command); - libssh2_channel_free(channel); - return NULL; - } - LIBSSH2_FREE(session, command); + /* Request SCP for the desired file */ + if (libssh2_channel_process_startup(channel, "exec", sizeof("exec") - 1, command, command_len)) { + /* previous call set libssh2_session_last_error(), pass it through */ + LIBSSH2_FREE(session, command); + libssh2_channel_free(channel); + return NULL; + } + LIBSSH2_FREE(session, command); - /* Wait for ACK */ - if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); - libssh2_channel_free(channel); - return NULL; - } + /* Wait for ACK */ + if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); + libssh2_channel_free(channel); + return NULL; + } - /* Send mtime and atime to be used for file */ - if (mtime || atime) { - response_len = snprintf(response, LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime, atime); - _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response); + /* Send mtime and atime to be used for file */ + if (mtime || atime) { + response_len = snprintf(response, LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime, atime); + _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response); - if (libssh2_channel_write(channel, response, response_len) != response_len) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0); - libssh2_channel_free(channel); - return NULL; - } - /* Wait for ACK */ - if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); - libssh2_channel_free(channel); - return NULL; - } - } + if (libssh2_channel_write(channel, response, response_len) != response_len) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0); + libssh2_channel_free(channel); + return NULL; + } + /* Wait for ACK */ + if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); + libssh2_channel_free(channel); + return NULL; + } + } - /* Send mode, size, and basename */ - base = strrchr(path, '/'); - if (base) { - base++; - } else { - base = path; - } + /* Send mode, size, and basename */ + base = strrchr(path, '/'); + if (base) { + base++; + } else { + base = path; + } - response_len = snprintf(response, LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode, (unsigned long)size, base); - _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response); - if (libssh2_channel_write(channel, response, response_len) != response_len) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0); - libssh2_channel_free(channel); - return NULL; - } - /* Wait for ACK */ - if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); - libssh2_channel_free(channel); - return NULL; - } + response_len = snprintf(response, LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode, (unsigned long)size, base); + _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", response); + if (libssh2_channel_write(channel, response, response_len) != response_len) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0); + libssh2_channel_free(channel); + return NULL; + } + /* Wait for ACK */ + if ((_libssh2_channel_read(channel, response, 1) <= 0) || (response[0] != 0)) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); + libssh2_channel_free(channel); + return NULL; + } - /* Ready to start, switch to non-blocking and let calling app send file */ - libssh2_channel_set_blocking(channel, 0); + /* Ready to start, switch to non-blocking and let calling app send file */ + libssh2_channel_set_blocking(channel, 0); - return channel; + return channel; } /* }}} */ diff --git a/src/session.c b/src/session.c index 95c7944..3ddacb9 100644 --- a/src/session.c +++ b/src/session.c @@ -50,8 +50,8 @@ */ static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc) { - (void)abstract; - return malloc(count); + (void)abstract; + return malloc(count); } /* }}} */ @@ -59,8 +59,8 @@ static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc) */ static LIBSSH2_FREE_FUNC(libssh2_default_free) { - (void)abstract; - free(ptr); + (void)abstract; + free(ptr); } /* }}} */ @@ -68,8 +68,8 @@ static LIBSSH2_FREE_FUNC(libssh2_default_free) */ static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc) { - (void)abstract; - return realloc(ptr, count); + (void)abstract; + return realloc(ptr, count); } /* }}} */ @@ -80,66 +80,66 @@ static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc) */ static int libssh2_banner_receive(LIBSSH2_SESSION *session) { - char banner[256]; - int banner_len = 0; + char banner[256]; + int banner_len = 0; - while ((banner_len < (int)sizeof(banner)) && - ((banner_len == 0) || (banner[banner_len-1] != '\n'))) { - char c = '\0'; - int ret; + while ((banner_len < (int)sizeof(banner)) && + ((banner_len == 0) || (banner[banner_len-1] != '\n'))) { + char c = '\0'; + int ret; - ret = recv(session->socket_fd, &c, 1, LIBSSH2_SOCKET_RECV_FLAGS(session)); + ret = recv(session->socket_fd, &c, 1, LIBSSH2_SOCKET_RECV_FLAGS(session)); - if (ret < 0) { + if (ret < 0) { #ifdef WIN32 - switch (WSAGetLastError()) { - case WSAEWOULDBLOCK: - errno = EAGAIN; - break; - case WSAENOTSOCK: - errno = EBADF; - break; - case WSAENOTCONN: - case WSAECONNABORTED: - errno = WSAENOTCONN; - break; - case WSAEINTR: - errno = EINTR; - break; - } + switch (WSAGetLastError()) { + case WSAEWOULDBLOCK: + errno = EAGAIN; + break; + case WSAENOTSOCK: + errno = EBADF; + break; + case WSAENOTCONN: + case WSAECONNABORTED: + errno = WSAENOTCONN; + break; + case WSAEINTR: + errno = EINTR; + break; + } #endif /* WIN32 */ - if (errno != EAGAIN) { - /* Some kinda error, but don't break for non-blocking issues */ - return 1; - } - } + if (errno != EAGAIN) { + /* Some kinda error, but don't break for non-blocking issues */ + return 1; + } + } - if (ret <= 0) continue; + if (ret <= 0) continue; - if (c == '\0') { - /* NULLs are not allowed in SSH banners */ - return 1; - } + if (c == '\0') { + /* NULLs are not allowed in SSH banners */ + return 1; + } - banner[banner_len++] = c; - } + banner[banner_len++] = c; + } - while (banner_len && - ((banner[banner_len-1] == '\n') || (banner[banner_len-1] == '\r'))) { - banner_len--; - } + while (banner_len && + ((banner[banner_len-1] == '\n') || (banner[banner_len-1] == '\r'))) { + banner_len--; + } - if (!banner_len) return 1; + if (!banner_len) return 1; - session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1); - if (!session->remote.banner) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocating space for remote banner", 0); - return 1; - } - memcpy(session->remote.banner, banner, banner_len); - session->remote.banner[banner_len] = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s", session->remote.banner); - return 0; + session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1); + if (!session->remote.banner) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Error allocating space for remote banner", 0); + return 1; + } + memcpy(session->remote.banner, banner, banner_len); + session->remote.banner[banner_len] = '\0'; + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s", session->remote.banner); + return 0; } /* }}} */ @@ -148,32 +148,32 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session) */ static int libssh2_banner_send(LIBSSH2_SESSION *session) { - char *banner = (char *)LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF; - int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1; + char *banner = (char *)LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF; + int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1; - if (session->local.banner) { - /* setopt_string will have given us our \r\n characters */ - banner_len = strlen((char *)session->local.banner); - banner = (char *)session->local.banner; - } + if (session->local.banner) { + /* setopt_string will have given us our \r\n characters */ + banner_len = strlen((char *)session->local.banner); + banner = (char *)session->local.banner; + } #ifdef LIBSSH2DEBUG { - /* Hack and slash to avoid sending CRLF in debug output */ - char banner_dup[256]; + /* Hack and slash to avoid sending CRLF in debug output */ + char banner_dup[256]; - if (banner_len < 256) { - memcpy(banner_dup, banner, banner_len - 2); - banner_dup[banner_len - 2] = '\0'; - } else { - memcpy(banner_dup, banner, 255); - banner[255] = '\0'; - } + if (banner_len < 256) { + memcpy(banner_dup, banner, banner_len - 2); + banner_dup[banner_len - 2] = '\0'; + } else { + memcpy(banner_dup, banner, 255); + banner[255] = '\0'; + } - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s", banner_dup); + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Sending Banner: %s", banner_dup); } #endif - return (send(session->socket_fd, banner, banner_len, LIBSSH2_SOCKET_SEND_FLAGS(session)) == banner_len) ? 0 : 1; + return (send(session->socket_fd, banner, banner_len, LIBSSH2_SOCKET_SEND_FLAGS(session)) == banner_len) ? 0 : 1; } /* }}} */ @@ -182,33 +182,33 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session) */ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner) { - int banner_len = banner ? strlen(banner) : 0; + int banner_len = banner ? strlen(banner) : 0; - if (session->local.banner) { - LIBSSH2_FREE(session, session->local.banner); - session->local.banner = NULL; - } + if (session->local.banner) { + LIBSSH2_FREE(session, session->local.banner); + session->local.banner = NULL; + } - if (!banner_len) { - return 0; - } + if (!banner_len) { + return 0; + } - session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3); - if (!session->local.banner) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate memory for local banner", 0); - return -1; - } + session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3); + if (!session->local.banner) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for local banner", 0); + return -1; + } - memcpy(session->local.banner, banner, banner_len); - session->local.banner[banner_len] = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_TRANS, - "Setting local Banner: %s", session->local.banner); - session->local.banner[banner_len++] = '\r'; - session->local.banner[banner_len++] = '\n'; - session->local.banner[banner_len++] = '\0'; + memcpy(session->local.banner, banner, banner_len); + session->local.banner[banner_len] = '\0'; + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "Setting local Banner: %s", session->local.banner); + session->local.banner[banner_len++] = '\r'; + session->local.banner[banner_len++] = '\n'; + session->local.banner[banner_len++] = '\0'; - return 0; + return 0; } /* }}} */ @@ -219,35 +219,35 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner) * An additional pointer value may be optionally passed to be sent to the callbacks (so they know who's asking) */ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex( - LIBSSH2_ALLOC_FUNC((*my_alloc)), - LIBSSH2_FREE_FUNC((*my_free)), - LIBSSH2_REALLOC_FUNC((*my_realloc)), - void *abstract) + LIBSSH2_ALLOC_FUNC((*my_alloc)), + LIBSSH2_FREE_FUNC((*my_free)), + LIBSSH2_REALLOC_FUNC((*my_realloc)), + void *abstract) { - LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc; - LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free; - LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc; - LIBSSH2_SESSION *session; + LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc; + LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free; + LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc; + LIBSSH2_SESSION *session; - if (my_alloc) - local_alloc = my_alloc; - if (my_free) - local_free = my_free; - if (my_realloc) - local_realloc = my_realloc; + if (my_alloc) + local_alloc = my_alloc; + if (my_free) + local_free = my_free; + if (my_realloc) + local_realloc = my_realloc; - session = local_alloc(sizeof(LIBSSH2_SESSION), abstract); - if (session) { - memset(session, 0, sizeof(LIBSSH2_SESSION)); - session->alloc = local_alloc; - session->free = local_free; - session->realloc = local_realloc; - session->abstract = abstract; - _libssh2_debug(session, LIBSSH2_DBG_TRANS, - "New session resource allocated"); - libssh2_crypto_init (); - } - return session; + session = local_alloc(sizeof(LIBSSH2_SESSION), abstract); + if (session) { + memset(session, 0, sizeof(LIBSSH2_SESSION)); + session->alloc = local_alloc; + session->free = local_free; + session->realloc = local_realloc; + session->abstract = abstract; + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "New session resource allocated"); + libssh2_crypto_init (); + } + return session; } /* }}} */ @@ -256,41 +256,41 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex( * Returns the prior address */ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, - int cbtype, - void *callback) + int cbtype, + void *callback) { - void *oldcb; + void *oldcb; - switch (cbtype) { - case LIBSSH2_CALLBACK_IGNORE: - oldcb = session->ssh_msg_ignore; - session->ssh_msg_ignore = callback; - return oldcb; + switch (cbtype) { + case LIBSSH2_CALLBACK_IGNORE: + oldcb = session->ssh_msg_ignore; + session->ssh_msg_ignore = callback; + return oldcb; - case LIBSSH2_CALLBACK_DEBUG: - oldcb = session->ssh_msg_debug; - session->ssh_msg_debug = callback; - return oldcb; + case LIBSSH2_CALLBACK_DEBUG: + oldcb = session->ssh_msg_debug; + session->ssh_msg_debug = callback; + return oldcb; - case LIBSSH2_CALLBACK_DISCONNECT: - oldcb = session->ssh_msg_disconnect; - session->ssh_msg_disconnect = callback; - return oldcb; + case LIBSSH2_CALLBACK_DISCONNECT: + oldcb = session->ssh_msg_disconnect; + session->ssh_msg_disconnect = callback; + return oldcb; - case LIBSSH2_CALLBACK_MACERROR: - oldcb = session->macerror; - session->macerror = callback; - return oldcb; + case LIBSSH2_CALLBACK_MACERROR: + oldcb = session->macerror; + session->macerror = callback; + return oldcb; - case LIBSSH2_CALLBACK_X11: - oldcb = session->x11; - session->x11 = callback; - return oldcb; + case LIBSSH2_CALLBACK_X11: + oldcb = session->x11; + session->x11 = callback; + return oldcb; - } - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting Callback %d", cbtype); + } + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Setting Callback %d", cbtype); - return NULL; + return NULL; } /* }}} */ @@ -303,75 +303,75 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, */ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket) { - unsigned char *data; - unsigned long data_len; - unsigned char service[sizeof("ssh-userauth") + 5 - 1]; - unsigned long service_length; - int rc; + unsigned char *data; + unsigned long data_len; + unsigned char service[sizeof("ssh-userauth") + 5 - 1]; + unsigned long service_length; + int rc; - _libssh2_debug(session, LIBSSH2_DBG_TRANS, - "session_startup for socket %d", socket); - /* FIXME: on some platforms (like win32) sockets are unsigned */ - if (socket < 0) { - /* Did we forget something? */ - libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE, - "Bad socket provided", 0); - return LIBSSH2_ERROR_SOCKET_NONE; - } - session->socket_fd = socket; + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "session_startup for socket %d", socket); + /* FIXME: on some platforms (like win32) sockets are unsigned */ + if (socket < 0) { + /* Did we forget something? */ + libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE, + "Bad socket provided", 0); + return LIBSSH2_ERROR_SOCKET_NONE; + } + session->socket_fd = socket; - /* TODO: Liveness check */ - if (libssh2_banner_send(session)) { - /* Unable to send banner? */ - libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, - "Error sending banner to remote host", 0); - return LIBSSH2_ERROR_BANNER_SEND; - } + /* TODO: Liveness check */ + if (libssh2_banner_send(session)) { + /* Unable to send banner? */ + libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, + "Error sending banner to remote host", 0); + return LIBSSH2_ERROR_BANNER_SEND; + } - if (libssh2_banner_receive(session)) { - /* Unable to receive banner from remote */ - libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, - "Timeout waiting for banner", 0); - return LIBSSH2_ERROR_BANNER_NONE; - } + if (libssh2_banner_receive(session)) { + /* Unable to receive banner from remote */ + libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, + "Timeout waiting for banner", 0); + return LIBSSH2_ERROR_BANNER_NONE; + } - rc = libssh2_kex_exchange(session, 0); - if(rc) { - libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, - "Unable to exchange encryption keys", 0); - return LIBSSH2_ERROR_KEX_FAILURE; - } + rc = libssh2_kex_exchange(session, 0); + if(rc) { + libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, + "Unable to exchange encryption keys", 0); + return LIBSSH2_ERROR_KEX_FAILURE; + } - _libssh2_debug(session, LIBSSH2_DBG_TRANS, - "Requesting userauth service"); - /* Request the userauth service */ - service[0] = SSH_MSG_SERVICE_REQUEST; - libssh2_htonu32(service + 1, sizeof("ssh-userauth") - 1); - memcpy(service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1); - if (libssh2_packet_write(session, service, - sizeof("ssh-userauth") + 5 - 1)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, - "Unable to ask for ssh-userauth service", 0); - return LIBSSH2_ERROR_SOCKET_SEND; - } + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "Requesting userauth service"); + /* Request the userauth service */ + service[0] = SSH_MSG_SERVICE_REQUEST; + libssh2_htonu32(service + 1, sizeof("ssh-userauth") - 1); + memcpy(service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1); + if (libssh2_packet_write(session, service, + sizeof("ssh-userauth") + 5 - 1)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to ask for ssh-userauth service", 0); + return LIBSSH2_ERROR_SOCKET_SEND; + } - rc = libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT, &data, - &data_len); - if(rc) { - return LIBSSH2_ERROR_SOCKET_DISCONNECT; - } - service_length = libssh2_ntohu32(data + 1); + rc = libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT, &data, + &data_len); + if(rc) { + return LIBSSH2_ERROR_SOCKET_DISCONNECT; + } + service_length = libssh2_ntohu32(data + 1); - if ((service_length != (sizeof("ssh-userauth") - 1)) || - strncmp("ssh-userauth", (char *)data + 5, service_length)) { - LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_PROTO, - "Invalid response received from server", 0); - return LIBSSH2_ERROR_PROTO; - } - LIBSSH2_FREE(session, data); + if ((service_length != (sizeof("ssh-userauth") - 1)) || + strncmp("ssh-userauth", (char *)data + 5, service_length)) { + LIBSSH2_FREE(session, data); + libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Invalid response received from server", 0); + return LIBSSH2_ERROR_PROTO; + } + LIBSSH2_FREE(session, data); - return 0; + return 0; } /* }}} */ @@ -381,124 +381,124 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket) */ LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session) { - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", session->remote.banner); - while (session->channels.head) { - LIBSSH2_CHANNEL *tmp = session->channels.head; + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", session->remote.banner); + while (session->channels.head) { + LIBSSH2_CHANNEL *tmp = session->channels.head; - libssh2_channel_free(session->channels.head); - if (tmp == session->channels.head) { - /* channel_free couldn't do it's job, perform a messy cleanup */ - tmp = session->channels.head; + libssh2_channel_free(session->channels.head); + if (tmp == session->channels.head) { + /* channel_free couldn't do it's job, perform a messy cleanup */ + tmp = session->channels.head; - /* unlink */ - session->channels.head = tmp->next; + /* unlink */ + session->channels.head = tmp->next; - /* free */ - LIBSSH2_FREE(session, tmp); + /* free */ + LIBSSH2_FREE(session, tmp); - /* reverse linking isn't important here, we're killing the structure */ - } - } + /* reverse linking isn't important here, we're killing the structure */ + } + } - while (session->listeners) { - libssh2_channel_forward_cancel(session->listeners); - } + while (session->listeners) { + libssh2_channel_forward_cancel(session->listeners); + } - if (session->state & LIBSSH2_STATE_NEWKEYS) { - /* hostkey */ - if (session->hostkey && session->hostkey->dtor) { - session->hostkey->dtor(session, &session->server_hostkey_abstract); - } + if (session->state & LIBSSH2_STATE_NEWKEYS) { + /* hostkey */ + if (session->hostkey && session->hostkey->dtor) { + session->hostkey->dtor(session, &session->server_hostkey_abstract); + } - /* Client to Server */ - /* crypt */ - if (session->local.crypt && session->local.crypt->dtor) { - session->local.crypt->dtor(session, &session->local.crypt_abstract); - } - /* comp */ - if (session->local.comp && session->local.comp->dtor) { - session->local.comp->dtor(session, 1, &session->local.comp_abstract); - } - /* mac */ - if (session->local.mac && session->local.mac->dtor) { - session->local.mac->dtor(session, &session->local.mac_abstract); - } + /* Client to Server */ + /* crypt */ + if (session->local.crypt && session->local.crypt->dtor) { + session->local.crypt->dtor(session, &session->local.crypt_abstract); + } + /* comp */ + if (session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, &session->local.comp_abstract); + } + /* mac */ + if (session->local.mac && session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } - /* Server to Client */ - /* crypt */ - if (session->remote.crypt && session->remote.crypt->dtor) { - session->remote.crypt->dtor(session, &session->remote.crypt_abstract); - } - /* comp */ - if (session->remote.comp && session->remote.comp->dtor) { - session->remote.comp->dtor(session, 0, &session->remote.comp_abstract); - } - /* mac */ - if (session->remote.mac && session->remote.mac->dtor) { - session->remote.mac->dtor(session, &session->remote.mac_abstract); - } + /* Server to Client */ + /* crypt */ + if (session->remote.crypt && session->remote.crypt->dtor) { + session->remote.crypt->dtor(session, &session->remote.crypt_abstract); + } + /* comp */ + if (session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, &session->remote.comp_abstract); + } + /* mac */ + if (session->remote.mac && session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } - /* session_id */ - if (session->session_id) { - LIBSSH2_FREE(session, session->session_id); - } - } + /* session_id */ + if (session->session_id) { + LIBSSH2_FREE(session, session->session_id); + } + } - /* Free banner(s) */ - if (session->remote.banner) { - LIBSSH2_FREE(session, session->remote.banner); - } - if (session->local.banner) { - LIBSSH2_FREE(session, session->local.banner); - } + /* Free banner(s) */ + if (session->remote.banner) { + LIBSSH2_FREE(session, session->remote.banner); + } + if (session->local.banner) { + LIBSSH2_FREE(session, session->local.banner); + } - /* Free preference(s) */ - if (session->kex_prefs) { - LIBSSH2_FREE(session, session->kex_prefs); - } - if (session->hostkey_prefs) { - LIBSSH2_FREE(session, session->hostkey_prefs); - } + /* Free preference(s) */ + if (session->kex_prefs) { + LIBSSH2_FREE(session, session->kex_prefs); + } + if (session->hostkey_prefs) { + LIBSSH2_FREE(session, session->hostkey_prefs); + } - if (session->local.crypt_prefs) { - LIBSSH2_FREE(session, session->local.crypt_prefs); - } - if (session->local.mac_prefs) { - LIBSSH2_FREE(session, session->local.mac_prefs); - } - if (session->local.comp_prefs) { - LIBSSH2_FREE(session, session->local.comp_prefs); - } - if (session->local.lang_prefs) { - LIBSSH2_FREE(session, session->local.lang_prefs); - } + if (session->local.crypt_prefs) { + LIBSSH2_FREE(session, session->local.crypt_prefs); + } + if (session->local.mac_prefs) { + LIBSSH2_FREE(session, session->local.mac_prefs); + } + if (session->local.comp_prefs) { + LIBSSH2_FREE(session, session->local.comp_prefs); + } + if (session->local.lang_prefs) { + LIBSSH2_FREE(session, session->local.lang_prefs); + } - if (session->remote.crypt_prefs) { - LIBSSH2_FREE(session, session->remote.crypt_prefs); - } - if (session->remote.mac_prefs) { - LIBSSH2_FREE(session, session->remote.mac_prefs); - } - if (session->remote.comp_prefs) { - LIBSSH2_FREE(session, session->remote.comp_prefs); - } - if (session->remote.lang_prefs) { - LIBSSH2_FREE(session, session->remote.lang_prefs); - } + if (session->remote.crypt_prefs) { + LIBSSH2_FREE(session, session->remote.crypt_prefs); + } + if (session->remote.mac_prefs) { + LIBSSH2_FREE(session, session->remote.mac_prefs); + } + if (session->remote.comp_prefs) { + LIBSSH2_FREE(session, session->remote.comp_prefs); + } + if (session->remote.lang_prefs) { + LIBSSH2_FREE(session, session->remote.lang_prefs); + } - /* Cleanup any remaining packets */ - while (session->packets.head) { - LIBSSH2_PACKET *tmp = session->packets.head; + /* Cleanup any remaining packets */ + while (session->packets.head) { + LIBSSH2_PACKET *tmp = session->packets.head; - /* unlink */ - session->packets.head = tmp->next; + /* unlink */ + session->packets.head = tmp->next; - /* free */ - LIBSSH2_FREE(session, tmp->data); - LIBSSH2_FREE(session, tmp); - } + /* free */ + LIBSSH2_FREE(session, tmp->data); + LIBSSH2_FREE(session, tmp); + } - LIBSSH2_FREE(session, session); + LIBSSH2_FREE(session, session); } /* }}} */ @@ -506,44 +506,44 @@ LIBSSH2_API void libssh2_session_free(LIBSSH2_SESSION *session) */ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang) { - unsigned char *s, *data; - unsigned long data_len, descr_len = 0, lang_len = 0; + unsigned char *s, *data; + unsigned long data_len, descr_len = 0, lang_len = 0; - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Disconnecting: reason=%d, desc=%s, lang=%s", reason, description, lang); - if (description) { - descr_len = strlen(description); - } - if (lang) { - lang_len = strlen(lang); - } - data_len = descr_len + lang_len + 13; /* packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */ + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Disconnecting: reason=%d, desc=%s, lang=%s", reason, description, lang); + if (description) { + descr_len = strlen(description); + } + if (lang) { + lang_len = strlen(lang); + } + data_len = descr_len + lang_len + 13; /* packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */ - s = data = LIBSSH2_ALLOC(session, data_len); - if (!data) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for disconnect packet", 0); - return -1; - } + s = data = LIBSSH2_ALLOC(session, data_len); + if (!data) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for disconnect packet", 0); + return -1; + } - *(s++) = SSH_MSG_DISCONNECT; - libssh2_htonu32(s, reason); s += 4; + *(s++) = SSH_MSG_DISCONNECT; + libssh2_htonu32(s, reason); s += 4; - libssh2_htonu32(s, descr_len); s += 4; - if (description) { - memcpy(s, description, descr_len); - s += descr_len; - } + libssh2_htonu32(s, descr_len); s += 4; + if (description) { + memcpy(s, description, descr_len); + s += descr_len; + } - libssh2_htonu32(s, lang_len); s += 4; - if (lang) { - memcpy(s, lang, lang_len); - s += lang_len; - } + libssh2_htonu32(s, lang_len); s += 4; + if (lang) { + memcpy(s, lang, lang_len); + s += lang_len; + } - libssh2_packet_write(session, data, data_len); + libssh2_packet_write(session, data, data_len); - LIBSSH2_FREE(session, data); + LIBSSH2_FREE(session, data); - return 0; + return 0; } /* }}} */ @@ -554,52 +554,52 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas */ LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type) { - /* All methods have char *name as their first element */ - const LIBSSH2_KEX_METHOD *method = NULL; + /* All methods have char *name as their first element */ + const LIBSSH2_KEX_METHOD *method = NULL; - switch(method_type) { - case LIBSSH2_METHOD_KEX: - method = session->kex; - break; - case LIBSSH2_METHOD_HOSTKEY: - method = (LIBSSH2_KEX_METHOD*)session->hostkey; - break; - case LIBSSH2_METHOD_CRYPT_CS: - method = (LIBSSH2_KEX_METHOD*)session->local.crypt; - break; - case LIBSSH2_METHOD_CRYPT_SC: - method = (LIBSSH2_KEX_METHOD*)session->remote.crypt; - break; - case LIBSSH2_METHOD_MAC_CS: - method = (LIBSSH2_KEX_METHOD*)session->local.mac; - break; - case LIBSSH2_METHOD_MAC_SC: - method = (LIBSSH2_KEX_METHOD*)session->remote.mac; - break; - case LIBSSH2_METHOD_COMP_CS: - method = (LIBSSH2_KEX_METHOD*)session->local.comp; - break; - case LIBSSH2_METHOD_COMP_SC: - method = (LIBSSH2_KEX_METHOD*)session->remote.comp; - break; - case LIBSSH2_METHOD_LANG_CS: - return ""; - break; - case LIBSSH2_METHOD_LANG_SC: - return ""; - break; - default: - libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type", 0); - return NULL; - break; - } + switch(method_type) { + case LIBSSH2_METHOD_KEX: + method = session->kex; + break; + case LIBSSH2_METHOD_HOSTKEY: + method = (LIBSSH2_KEX_METHOD*)session->hostkey; + break; + case LIBSSH2_METHOD_CRYPT_CS: + method = (LIBSSH2_KEX_METHOD*)session->local.crypt; + break; + case LIBSSH2_METHOD_CRYPT_SC: + method = (LIBSSH2_KEX_METHOD*)session->remote.crypt; + break; + case LIBSSH2_METHOD_MAC_CS: + method = (LIBSSH2_KEX_METHOD*)session->local.mac; + break; + case LIBSSH2_METHOD_MAC_SC: + method = (LIBSSH2_KEX_METHOD*)session->remote.mac; + break; + case LIBSSH2_METHOD_COMP_CS: + method = (LIBSSH2_KEX_METHOD*)session->local.comp; + break; + case LIBSSH2_METHOD_COMP_SC: + method = (LIBSSH2_KEX_METHOD*)session->remote.comp; + break; + case LIBSSH2_METHOD_LANG_CS: + return ""; + break; + case LIBSSH2_METHOD_LANG_SC: + return ""; + break; + default: + libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid parameter specified for method_type", 0); + return NULL; + break; + } - if (!method) { - libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No method negotiated", 0); - return NULL; - } + if (!method) { + libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No method negotiated", 0); + return NULL; + } - return method->name; + return method->name; } /* }}} */ @@ -608,7 +608,7 @@ LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int me */ LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session) { - return &session->abstract; + return &session->abstract; } /* }}} */ @@ -619,54 +619,54 @@ LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session) */ LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, - int *errmsg_len, int want_buf) + int *errmsg_len, int want_buf) { - /* No error to report */ - if (!session->err_code) { - if (errmsg) { - if (want_buf) { - *errmsg = LIBSSH2_ALLOC(session, 1); - if (*errmsg) { - **errmsg = 0; - } - } else { - *errmsg = (char *)""; - } - } - if (errmsg_len) { - *errmsg_len = 0; - } - return 0; - } + /* No error to report */ + if (!session->err_code) { + if (errmsg) { + if (want_buf) { + *errmsg = LIBSSH2_ALLOC(session, 1); + if (*errmsg) { + **errmsg = 0; + } + } else { + *errmsg = (char *)""; + } + } + if (errmsg_len) { + *errmsg_len = 0; + } + return 0; + } - if (errmsg) { - char *serrmsg = session->err_msg ? session->err_msg : - (char *)""; - int ownbuf = session->err_msg ? session->err_should_free : 0; + if (errmsg) { + char *serrmsg = session->err_msg ? session->err_msg : + (char *)""; + int ownbuf = session->err_msg ? session->err_should_free : 0; - if (want_buf) { - if (ownbuf) { - /* Just give the calling program the buffer */ - *errmsg = serrmsg; - session->err_should_free = 0; - } else { - /* Make a copy so the calling program can own it */ - *errmsg = LIBSSH2_ALLOC(session, session->err_msglen + 1); - if (*errmsg) { - memcpy(*errmsg, session->err_msg, session->err_msglen); - (*errmsg)[session->err_msglen] = 0; - } - } - } else { - *errmsg = serrmsg; - } - } + if (want_buf) { + if (ownbuf) { + /* Just give the calling program the buffer */ + *errmsg = serrmsg; + session->err_should_free = 0; + } else { + /* Make a copy so the calling program can own it */ + *errmsg = LIBSSH2_ALLOC(session, session->err_msglen + 1); + if (*errmsg) { + memcpy(*errmsg, session->err_msg, session->err_msglen); + (*errmsg)[session->err_msglen] = 0; + } + } + } else { + *errmsg = serrmsg; + } + } - if (errmsg_len) { - *errmsg_len = session->err_msglen; - } + if (errmsg_len) { + *errmsg_len = session->err_msglen; + } - return session->err_code; + return session->err_code; } /* }}} */ @@ -676,13 +676,13 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, */ LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value) { - if (value) { - session->flags |= flag; - } else { - session->flags &= ~flag; - } + if (value) { + session->flags |= flag; + } else { + session->flags &= ~flag; + } - return session->flags; + return session->flags; } /* }}} */ @@ -692,19 +692,19 @@ LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int val */ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended) { - LIBSSH2_SESSION *session = channel->session; - LIBSSH2_PACKET *packet = session->packets.head; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_PACKET *packet = session->packets.head; - while (packet) { - if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) && (extended == 0) && (channel->local.id == libssh2_ntohu32(packet->data + 1))) || - ((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (extended != 0) && (channel->local.id == libssh2_ntohu32(packet->data + 1)))) { - /* Found data waiting to be read */ - return 1; - } - packet = packet->next; - } + while (packet) { + if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) && (extended == 0) && (channel->local.id == libssh2_ntohu32(packet->data + 1))) || + ((packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && (extended != 0) && (channel->local.id == libssh2_ntohu32(packet->data + 1)))) { + /* Found data waiting to be read */ + return 1; + } + packet = packet->next; + } - return 0; + return 0; } /* }}} */ @@ -714,7 +714,7 @@ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended */ static inline int libssh2_poll_channel_write(LIBSSH2_CHANNEL *channel) { - return channel->local.window_size ? 1 : 0; + return channel->local.window_size ? 1 : 0; } /* }}} */ @@ -724,7 +724,7 @@ static inline int libssh2_poll_channel_write(LIBSSH2_CHANNEL *channel) */ static inline int libssh2_poll_listener_queued(LIBSSH2_LISTENER *listener) { - return listener->queue ? 1 : 0; + return listener->queue ? 1 : 0; } /* }}} */ @@ -732,248 +732,248 @@ static inline int libssh2_poll_listener_queued(LIBSSH2_LISTENER *listener) * Poll sockets, channels, and listeners for activity */ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, - long timeout) + long timeout) { - long timeout_remaining; - unsigned int i, active_fds; + long timeout_remaining; + unsigned int i, active_fds; #ifdef HAVE_POLL - LIBSSH2_SESSION *session = NULL; - struct pollfd sockets[nfds]; - /* FIXME: (dast) this is not C89 code! However, the prototype for this - function doesn't provide a session struct so we can't easily use - the user-provided malloc replacement here... I suggest we modify - the proto to make it possible. */ + LIBSSH2_SESSION *session = NULL; + struct pollfd sockets[nfds]; + /* FIXME: (dast) this is not C89 code! However, the prototype for this + function doesn't provide a session struct so we can't easily use + the user-provided malloc replacement here... I suggest we modify + the proto to make it possible. */ - /* Setup sockets for polling */ - for(i = 0; i < nfds; i++) { - fds[i].revents = 0; - switch (fds[i].type) { - case LIBSSH2_POLLFD_SOCKET: - sockets[i].fd = fds[i].fd.socket; - sockets[i].events = fds[i].events; - sockets[i].revents = 0; - break; - case LIBSSH2_POLLFD_CHANNEL: - sockets[i].fd = fds[i].fd.channel->session->socket_fd; - sockets[i].events = POLLIN; - sockets[i].revents = 0; - if (!session) session = fds[i].fd.channel->session; - break; - case LIBSSH2_POLLFD_LISTENER: - sockets[i].fd = fds[i].fd.listener->session->socket_fd; - sockets[i].events = POLLIN; - sockets[i].revents = 0; - if (!session) session = fds[i].fd.listener->session; - break; - default: - if (session) libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, "Invalid descriptor passed to libssh2_poll()", 0); - return -1; - } - } + /* Setup sockets for polling */ + for(i = 0; i < nfds; i++) { + fds[i].revents = 0; + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + sockets[i].fd = fds[i].fd.socket; + sockets[i].events = fds[i].events; + sockets[i].revents = 0; + break; + case LIBSSH2_POLLFD_CHANNEL: + sockets[i].fd = fds[i].fd.channel->session->socket_fd; + sockets[i].events = POLLIN; + sockets[i].revents = 0; + if (!session) session = fds[i].fd.channel->session; + break; + case LIBSSH2_POLLFD_LISTENER: + sockets[i].fd = fds[i].fd.listener->session->socket_fd; + sockets[i].events = POLLIN; + sockets[i].revents = 0; + if (!session) session = fds[i].fd.listener->session; + break; + default: + if (session) libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, "Invalid descriptor passed to libssh2_poll()", 0); + return -1; + } + } #elif defined(HAVE_SELECT) - LIBSSH2_SESSION *session = NULL; - int maxfd = 0; - fd_set rfds,wfds; - struct timeval tv; + LIBSSH2_SESSION *session = NULL; + int maxfd = 0; + fd_set rfds,wfds; + struct timeval tv; - FD_ZERO(&rfds); - FD_ZERO(&wfds); - for(i = 0; i < nfds; i++) { - fds[i].revents = 0; - switch (fds[i].type) { - case LIBSSH2_POLLFD_SOCKET: - if (fds[i].events & LIBSSH2_POLLFD_POLLIN) { - FD_SET(fds[i].fd.socket, &rfds); - if (fds[i].fd.socket > maxfd) maxfd = fds[i].fd.socket; - } - if (fds[i].events & LIBSSH2_POLLFD_POLLOUT) { - FD_SET(fds[i].fd.socket, &wfds); - if (fds[i].fd.socket > maxfd) maxfd = fds[i].fd.socket; - } - break; - case LIBSSH2_POLLFD_CHANNEL: - FD_SET(fds[i].fd.channel->session->socket_fd, &rfds); - if (fds[i].fd.channel->session->socket_fd > maxfd) maxfd = fds[i].fd.channel->session->socket_fd; - if (!session) session = fds[i].fd.channel->session; - break; - case LIBSSH2_POLLFD_LISTENER: - FD_SET(fds[i].fd.listener->session->socket_fd, &rfds); - if (fds[i].fd.listener->session->socket_fd > maxfd) maxfd = fds[i].fd.listener->session->socket_fd; - if (!session) session = fds[i].fd.listener->session; - break; - default: - if (session) libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, "Invalid descriptor passed to libssh2_poll()", 0); - return -1; - } - } + FD_ZERO(&rfds); + FD_ZERO(&wfds); + for(i = 0; i < nfds; i++) { + fds[i].revents = 0; + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + if (fds[i].events & LIBSSH2_POLLFD_POLLIN) { + FD_SET(fds[i].fd.socket, &rfds); + if (fds[i].fd.socket > maxfd) maxfd = fds[i].fd.socket; + } + if (fds[i].events & LIBSSH2_POLLFD_POLLOUT) { + FD_SET(fds[i].fd.socket, &wfds); + if (fds[i].fd.socket > maxfd) maxfd = fds[i].fd.socket; + } + break; + case LIBSSH2_POLLFD_CHANNEL: + FD_SET(fds[i].fd.channel->session->socket_fd, &rfds); + if (fds[i].fd.channel->session->socket_fd > maxfd) maxfd = fds[i].fd.channel->session->socket_fd; + if (!session) session = fds[i].fd.channel->session; + break; + case LIBSSH2_POLLFD_LISTENER: + FD_SET(fds[i].fd.listener->session->socket_fd, &rfds); + if (fds[i].fd.listener->session->socket_fd > maxfd) maxfd = fds[i].fd.listener->session->socket_fd; + if (!session) session = fds[i].fd.listener->session; + break; + default: + if (session) libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, "Invalid descriptor passed to libssh2_poll()", 0); + return -1; + } + } #else - /* No select() or poll() - * no sockets sturcture to setup - */ + /* No select() or poll() + * no sockets sturcture to setup + */ - timeout = 0; + timeout = 0; #endif /* HAVE_POLL or HAVE_SELECT */ - timeout_remaining = timeout; - do { + timeout_remaining = timeout; + do { #if defined(HAVE_POLL) || defined(HAVE_SELECT) - int sysret; + int sysret; #endif - active_fds = 0; + active_fds = 0; - for (i = 0; i < nfds; i++) { - if (fds[i].events != fds[i].revents) { - switch (fds[i].type) { - case LIBSSH2_POLLFD_CHANNEL: - if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want to be ready for read */ - ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* Not yet known to be ready for read */ - fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 0) ? LIBSSH2_POLLFD_POLLIN : 0; - } - if ((fds[i].events & LIBSSH2_POLLFD_POLLEXT) && /* Want to be ready for extended read */ - ((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) { /* Not yet known to be ready for extended read */ - fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 1) ? LIBSSH2_POLLFD_POLLEXT : 0; - } - if ((fds[i].events & LIBSSH2_POLLFD_POLLOUT) && /* Want to be ready for write */ - ((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) { /* Not yet known to be ready for write */ - fds[i].revents |= libssh2_poll_channel_write(fds[i].fd.channel) ? LIBSSH2_POLLFD_POLLOUT : 0; - } - if (fds[i].fd.channel->remote.close || fds[i].fd.channel->local.close) { - fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED; - } - if (fds[i].fd.channel->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { - fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; - } - break; - case LIBSSH2_POLLFD_LISTENER: - if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want a connection */ - ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* No connections known of yet */ - fds[i].revents |= libssh2_poll_listener_queued(fds[i].fd.listener) ? LIBSSH2_POLLFD_POLLIN : 0; - } - if (fds[i].fd.listener->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { - fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; - } - break; - } - } - if (fds[i].revents) { - active_fds++; - } - } + for (i = 0; i < nfds; i++) { + if (fds[i].events != fds[i].revents) { + switch (fds[i].type) { + case LIBSSH2_POLLFD_CHANNEL: + if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want to be ready for read */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* Not yet known to be ready for read */ + fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 0) ? LIBSSH2_POLLFD_POLLIN : 0; + } + if ((fds[i].events & LIBSSH2_POLLFD_POLLEXT) && /* Want to be ready for extended read */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) { /* Not yet known to be ready for extended read */ + fds[i].revents |= libssh2_poll_channel_read(fds[i].fd.channel, 1) ? LIBSSH2_POLLFD_POLLEXT : 0; + } + if ((fds[i].events & LIBSSH2_POLLFD_POLLOUT) && /* Want to be ready for write */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) { /* Not yet known to be ready for write */ + fds[i].revents |= libssh2_poll_channel_write(fds[i].fd.channel) ? LIBSSH2_POLLFD_POLLOUT : 0; + } + if (fds[i].fd.channel->remote.close || fds[i].fd.channel->local.close) { + fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED; + } + if (fds[i].fd.channel->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { + fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; + } + break; + case LIBSSH2_POLLFD_LISTENER: + if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && /* Want a connection */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { /* No connections known of yet */ + fds[i].revents |= libssh2_poll_listener_queued(fds[i].fd.listener) ? LIBSSH2_POLLFD_POLLIN : 0; + } + if (fds[i].fd.listener->session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { + fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; + } + break; + } + } + if (fds[i].revents) { + active_fds++; + } + } - if (active_fds) { - /* Don't block on the sockets if we have channels/listeners which are ready */ - timeout_remaining = 0; - } + if (active_fds) { + /* Don't block on the sockets if we have channels/listeners which are ready */ + timeout_remaining = 0; + } #ifdef HAVE_POLL #ifdef HAVE_GETTIMEOFDAY { - struct timeval tv_begin, tv_end; + struct timeval tv_begin, tv_end; - gettimeofday((struct timeval *)&tv_begin, NULL); - sysret = poll(sockets, nfds, timeout_remaining); - gettimeofday((struct timeval *)&tv_end, NULL); - timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; - timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; + gettimeofday((struct timeval *)&tv_begin, NULL); + sysret = poll(sockets, nfds, timeout_remaining); + gettimeofday((struct timeval *)&tv_end, NULL); + timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; + timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; } #else - /* If the platform doesn't support gettimeofday, - * then just make the call non-blocking and walk away - */ - sysret = poll(sockets, nfds, timeout_remaining); - timeout_remaining = 0; + /* If the platform doesn't support gettimeofday, + * then just make the call non-blocking and walk away + */ + sysret = poll(sockets, nfds, timeout_remaining); + timeout_remaining = 0; #endif /* HAVE_GETTIMEOFDAY */ - if (sysret > 0) { - for (i = 0; i < nfds; i++) { - switch (fds[i].type) { - case LIBSSH2_POLLFD_SOCKET: - fds[i].revents = sockets[i].revents; - sockets[i].revents = 0; /* In case we loop again, be nice */ - if (fds[i].revents) { - active_fds++; - } - break; - case LIBSSH2_POLLFD_CHANNEL: - if (sockets[i].events & POLLIN) { - /* Spin session until no data available */ - while (libssh2_packet_read(fds[i].fd.channel->session) > 0); - } - if (sockets[i].revents & POLLHUP) { - fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; - } - sockets[i].revents = 0; - break; - case LIBSSH2_POLLFD_LISTENER: - if (sockets[i].events & POLLIN) { - /* Spin session until no data available */ - while (libssh2_packet_read(fds[i].fd.listener->session) > 0); - } - if (sockets[i].revents & POLLHUP) { - fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; - } - sockets[i].revents = 0; - break; - } - } - } + if (sysret > 0) { + for (i = 0; i < nfds; i++) { + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + fds[i].revents = sockets[i].revents; + sockets[i].revents = 0; /* In case we loop again, be nice */ + if (fds[i].revents) { + active_fds++; + } + break; + case LIBSSH2_POLLFD_CHANNEL: + if (sockets[i].events & POLLIN) { + /* Spin session until no data available */ + while (libssh2_packet_read(fds[i].fd.channel->session) > 0); + } + if (sockets[i].revents & POLLHUP) { + fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; + } + sockets[i].revents = 0; + break; + case LIBSSH2_POLLFD_LISTENER: + if (sockets[i].events & POLLIN) { + /* Spin session until no data available */ + while (libssh2_packet_read(fds[i].fd.listener->session) > 0); + } + if (sockets[i].revents & POLLHUP) { + fds[i].revents |= LIBSSH2_POLLFD_LISTENER_CLOSED | LIBSSH2_POLLFD_SESSION_CLOSED; + } + sockets[i].revents = 0; + break; + } + } + } #elif defined(HAVE_SELECT) - tv.tv_sec = timeout_remaining / 1000; - tv.tv_usec = (timeout_remaining % 1000) * 1000; + tv.tv_sec = timeout_remaining / 1000; + tv.tv_usec = (timeout_remaining % 1000) * 1000; #ifdef HAVE_GETTIMEOFDAY { - struct timeval tv_begin, tv_end; + struct timeval tv_begin, tv_end; - gettimeofday((struct timeval *)&tv_begin, NULL); - sysret = select(maxfd, &rfds, &wfds, NULL, &tv); - gettimeofday((struct timeval *)&tv_end, NULL); + gettimeofday((struct timeval *)&tv_begin, NULL); + sysret = select(maxfd, &rfds, &wfds, NULL, &tv); + gettimeofday((struct timeval *)&tv_end, NULL); - timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; - timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; + timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; + timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; } #else - /* If the platform doesn't support gettimeofday, - * then just make the call non-blocking and walk away - */ - sysret = select(maxfd, &rfds, &wfds, NULL, &tv); - timeout_remaining = 0; + /* If the platform doesn't support gettimeofday, + * then just make the call non-blocking and walk away + */ + sysret = select(maxfd, &rfds, &wfds, NULL, &tv); + timeout_remaining = 0; #endif - if (sysret > 0) { - for (i = 0; i < nfds; i++) { - switch (fds[i].type) { - case LIBSSH2_POLLFD_SOCKET: - if (FD_ISSET(fds[i].fd.socket, &rfds)) { - fds[i].revents |= LIBSSH2_POLLFD_POLLIN; - } - if (FD_ISSET(fds[i].fd.socket, &wfds)) { - fds[i].revents |= LIBSSH2_POLLFD_POLLOUT; - } - if (fds[i].revents) { - active_fds++; - } - break; - case LIBSSH2_POLLFD_CHANNEL: - if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) { - /* Spin session until no data available */ - while (libssh2_packet_read(fds[i].fd.channel->session) > 0); - } - break; - case LIBSSH2_POLLFD_LISTENER: - if (FD_ISSET(fds[i].fd.listener->session->socket_fd, &rfds)) { - /* Spin session until no data available */ - while (libssh2_packet_read(fds[i].fd.listener->session) > 0); - } - break; - } - } - } + if (sysret > 0) { + for (i = 0; i < nfds; i++) { + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + if (FD_ISSET(fds[i].fd.socket, &rfds)) { + fds[i].revents |= LIBSSH2_POLLFD_POLLIN; + } + if (FD_ISSET(fds[i].fd.socket, &wfds)) { + fds[i].revents |= LIBSSH2_POLLFD_POLLOUT; + } + if (fds[i].revents) { + active_fds++; + } + break; + case LIBSSH2_POLLFD_CHANNEL: + if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) { + /* Spin session until no data available */ + while (libssh2_packet_read(fds[i].fd.channel->session) > 0); + } + break; + case LIBSSH2_POLLFD_LISTENER: + if (FD_ISSET(fds[i].fd.listener->session->socket_fd, &rfds)) { + /* Spin session until no data available */ + while (libssh2_packet_read(fds[i].fd.listener->session) > 0); + } + break; + } + } + } #endif /* else no select() or poll() -- timeout (and by extension timeout_remaining) will be equal to 0 */ - } while ((timeout_remaining > 0) && !active_fds); + } while ((timeout_remaining > 0) && !active_fds); - return active_fds; + return active_fds; } /* }}} */ diff --git a/src/sftp.c b/src/sftp.c index ef96e03..d04e77f 100644 --- a/src/sftp.c +++ b/src/sftp.c @@ -150,24 +150,24 @@ struct _LIBSSH2_SFTP { #define LIBSSH2_SFTP_ATTR_PFILETYPE_DIR 0040000 struct _LIBSSH2_SFTP_HANDLE { - LIBSSH2_SFTP *sftp; - LIBSSH2_SFTP_HANDLE *prev, *next; - - char *handle; - int handle_len; - - char handle_type; - - union _libssh2_sftp_handle_data { - struct _libssh2_sftp_handle_file_data { - libssh2_uint64_t offset; - } file; - struct _libssh2_sftp_handle_dir_data { - unsigned long names_left; - void *names_packet; - char *next_name; - } dir; - } u; + LIBSSH2_SFTP *sftp; + LIBSSH2_SFTP_HANDLE *prev, *next; + + char *handle; + int handle_len; + + char handle_type; + + union _libssh2_sftp_handle_data { + struct _libssh2_sftp_handle_file_data { + libssh2_uint64_t offset; + } file; + struct _libssh2_sftp_handle_dir_data { + unsigned long names_left; + void *names_packet; + char *next_name; + } dir; + } u; }; /* {{{ libssh2_sftp_packet_add @@ -176,31 +176,31 @@ struct _LIBSSH2_SFTP_HANDLE { /* libssh2_sftp_packet_add - NB-SAFE */ static int libssh2_sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data, unsigned long data_len) { - LIBSSH2_SESSION *session = sftp->channel->session; - LIBSSH2_PACKET *packet; - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Received packet %d", (int)data[0]); - packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate datablock for SFTP packet", 0); - return -1; - } - memset(packet, 0, sizeof(LIBSSH2_PACKET)); - - packet->data = data; - packet->data_len = data_len; - packet->data_head = 5; - packet->brigade = &sftp->packets; - packet->next = NULL; - packet->prev = sftp->packets.tail; - if (packet->prev) { - packet->prev->next = packet; - } else { - sftp->packets.head = packet; - } - sftp->packets.tail = packet; - - return 0; + LIBSSH2_SESSION *session = sftp->channel->session; + LIBSSH2_PACKET *packet; + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Received packet %d", (int)data[0]); + packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate datablock for SFTP packet", 0); + return -1; + } + memset(packet, 0, sizeof(LIBSSH2_PACKET)); + + packet->data = data; + packet->data_len = data_len; + packet->data_head = 5; + packet->brigade = &sftp->packets; + packet->next = NULL; + packet->prev = sftp->packets.tail; + if (packet->prev) { + packet->prev->next = packet; + } else { + sftp->packets.head = packet; + } + sftp->packets.tail = packet; + + return 0; } /* }}} */ @@ -365,33 +365,33 @@ static int libssh2_sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type static int libssh2_sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type, unsigned long request_id, unsigned char **data, unsigned long *data_len) { - LIBSSH2_SESSION *session = sftp->channel->session; + LIBSSH2_SESSION *session = sftp->channel->session; int bl; - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Requiring %d packet", (int)packet_type); - - if (libssh2_sftp_packet_ask(sftp, packet_type, request_id, data, data_len, 0) == 0) { - /* The right packet was available in the packet brigade */ - return 0; - } - - bl = libssh2_channel_get_blocking(sftp->channel); - while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { - int ret = libssh2_sftp_packet_read(sftp, bl, 0); - if (!bl && (ret == PACKET_EAGAIN)) { - return PACKET_EAGAIN; - } - else if (ret <= 0) { - return -1; - } - - if (packet_type == ret) { - /* Be lazy, let packet_ask pull it out of the brigade */ - return libssh2_sftp_packet_ask(sftp, packet_type, request_id, data, data_len, 0); - } - } - - /* Only reached if the socket died */ - return -1; + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Requiring %d packet", (int)packet_type); + + if (libssh2_sftp_packet_ask(sftp, packet_type, request_id, data, data_len, 0) == 0) { + /* The right packet was available in the packet brigade */ + return 0; + } + + bl = libssh2_channel_get_blocking(sftp->channel); + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + int ret = libssh2_sftp_packet_read(sftp, bl, 0); + if (!bl && (ret == PACKET_EAGAIN)) { + return PACKET_EAGAIN; + } + else if (ret <= 0) { + return -1; + } + + if (packet_type == ret) { + /* Be lazy, let packet_ask pull it out of the brigade */ + return libssh2_sftp_packet_ask(sftp, packet_type, request_id, data, data_len, 0); + } + } + + /* Only reached if the socket died */ + return -1; } /* }}} */ @@ -471,18 +471,18 @@ static int libssh2_sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_respon /* libssh2_sftp_attrsize - NB-SAFE */ static int libssh2_sftp_attrsize(const LIBSSH2_SFTP_ATTRIBUTES *attrs) { - int attrsize = 4; /* flags(4) */ - - if (!attrs) { - return attrsize; - } - - if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) attrsize += 8; - if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) attrsize += 8; - if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) attrsize += 4; - if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) attrsize += 8; /* atime + mtime as u32 */ - + int attrsize = 4; /* flags(4) */ + + if (!attrs) { return attrsize; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) attrsize += 8; + if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) attrsize += 8; + if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) attrsize += 4; + if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) attrsize += 8; /* atime + mtime as u32 */ + + return attrsize; } /* }}} */ @@ -492,37 +492,37 @@ static int libssh2_sftp_attrsize(const LIBSSH2_SFTP_ATTRIBUTES *attrs) /* libssh2_sftp_attr2bin - NB-SAFE */ static int libssh2_sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES *attrs) { - unsigned char *s = p; - unsigned long flag_mask = LIBSSH2_SFTP_ATTR_SIZE | LIBSSH2_SFTP_ATTR_UIDGID | LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME; - - /* TODO: When we add SFTP4+ functionality flag_mask can get additional bits */ - - if (!attrs) { - libssh2_htonu32(s, 0); - return 4; - } - - libssh2_htonu32(s, attrs->flags & flag_mask); s += 4; - - if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { - libssh2_htonu64(s, attrs->filesize); s += 8; - } - - if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { - libssh2_htonu32(s, attrs->uid); s += 4; - libssh2_htonu32(s, attrs->gid); s += 4; - } - - if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { - libssh2_htonu32(s, attrs->permissions); s += 4; - } - - if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { - libssh2_htonu32(s, attrs->atime); s += 4; - libssh2_htonu32(s, attrs->mtime); s += 4; - } - - return (s - p); + unsigned char *s = p; + unsigned long flag_mask = LIBSSH2_SFTP_ATTR_SIZE | LIBSSH2_SFTP_ATTR_UIDGID | LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME; + + /* TODO: When we add SFTP4+ functionality flag_mask can get additional bits */ + + if (!attrs) { + libssh2_htonu32(s, 0); + return 4; + } + + libssh2_htonu32(s, attrs->flags & flag_mask); s += 4; + + if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { + libssh2_htonu64(s, attrs->filesize); s += 8; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { + libssh2_htonu32(s, attrs->uid); s += 4; + libssh2_htonu32(s, attrs->gid); s += 4; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { + libssh2_htonu32(s, attrs->permissions); s += 4; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { + libssh2_htonu32(s, attrs->atime); s += 4; + libssh2_htonu32(s, attrs->mtime); s += 4; + } + + return (s - p); } /* }}} */ @@ -531,30 +531,30 @@ static int libssh2_sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES /* libssh2_sftp_bin2attr - NB-SAFE */ static int libssh2_sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES *attrs, const unsigned char *p) { - const unsigned char *s = p; - - memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); - attrs->flags = libssh2_ntohu32(s); s += 4; - - if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { - attrs->filesize = libssh2_ntohu64(s); s += 8; - } - - if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { - attrs->uid = libssh2_ntohu32(s); s += 4; - attrs->gid = libssh2_ntohu32(s); s += 4; - } - - if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { - attrs->permissions = libssh2_ntohu32(s); s += 4; - } - - if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { - attrs->atime = libssh2_ntohu32(s); s += 4; - attrs->mtime = libssh2_ntohu32(s); s += 4; - } - - return (s - p); + const unsigned char *s = p; + + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + attrs->flags = libssh2_ntohu32(s); s += 4; + + if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { + attrs->filesize = libssh2_ntohu64(s); s += 8; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { + attrs->uid = libssh2_ntohu32(s); s += 4; + attrs->gid = libssh2_ntohu32(s); s += 4; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { + attrs->permissions = libssh2_ntohu32(s); s += 4; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { + attrs->atime = libssh2_ntohu32(s); s += 4; + attrs->mtime = libssh2_ntohu32(s); s += 4; + } + + return (s - p); } /* }}} */ @@ -715,99 +715,99 @@ LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp) /* libssh2_sftp_open_ex - NB-UNSAFE?? */ LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len, unsigned long flags, long mode, int open_type) { - LIBSSH2_CHANNEL *channel = sftp->channel; - LIBSSH2_SESSION *session = channel->session; - LIBSSH2_SFTP_HANDLE *fp; - LIBSSH2_SFTP_ATTRIBUTES attrs = { - LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 - }; - unsigned long data_len; - ssize_t packet_len = filename_len + 13 + ((open_type == LIBSSH2_SFTP_OPENFILE) ? (4 + libssh2_sftp_attrsize(&attrs)) : 0); - /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) + flags(4) */ - unsigned char *packet, *data, *s; - static const unsigned char fopen_responses[2] = { SSH_FXP_HANDLE, SSH_FXP_STATUS }; - unsigned long request_id; - int rc; - - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_OPEN or FXP_OPENDIR packet", 0); - return NULL; - } - /* Filetype in SFTP 3 and earlier */ - attrs.permissions = mode | ((open_type == LIBSSH2_SFTP_OPENFILE) ? LIBSSH2_SFTP_ATTR_PFILETYPE_FILE : LIBSSH2_SFTP_ATTR_PFILETYPE_DIR); - - libssh2_htonu32(s, packet_len - 4); s += 4; - *(s++) = (open_type == LIBSSH2_SFTP_OPENFILE) ? SSH_FXP_OPEN : SSH_FXP_OPENDIR; - request_id = sftp->request_id++; - libssh2_htonu32(s, request_id); s += 4; - libssh2_htonu32(s, filename_len); s += 4; - memcpy(s, filename, filename_len); s += filename_len; - if (open_type == LIBSSH2_SFTP_OPENFILE) { - libssh2_htonu32(s, flags); s += 4; - s += libssh2_sftp_attr2bin(s, &attrs); - } - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Sending %s open request", (open_type == LIBSSH2_SFTP_OPENFILE) ? "file" : "directory"); - if (packet_len != _libssh2_channel_write(channel, (char *)packet, - packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_OPEN or FXP_OPENDIR command", 0); - LIBSSH2_FREE(session, packet); - return NULL; - } + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_HANDLE *fp; + LIBSSH2_SFTP_ATTRIBUTES attrs = { + LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 + }; + unsigned long data_len; + ssize_t packet_len = filename_len + 13 + ((open_type == LIBSSH2_SFTP_OPENFILE) ? (4 + libssh2_sftp_attrsize(&attrs)) : 0); + /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) + flags(4) */ + unsigned char *packet, *data, *s; + static const unsigned char fopen_responses[2] = { SSH_FXP_HANDLE, SSH_FXP_STATUS }; + unsigned long request_id; + int rc; + + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_OPEN or FXP_OPENDIR packet", 0); + return NULL; + } + /* Filetype in SFTP 3 and earlier */ + attrs.permissions = mode | ((open_type == LIBSSH2_SFTP_OPENFILE) ? LIBSSH2_SFTP_ATTR_PFILETYPE_FILE : LIBSSH2_SFTP_ATTR_PFILETYPE_DIR); + + libssh2_htonu32(s, packet_len - 4); s += 4; + *(s++) = (open_type == LIBSSH2_SFTP_OPENFILE) ? SSH_FXP_OPEN : SSH_FXP_OPENDIR; + request_id = sftp->request_id++; + libssh2_htonu32(s, request_id); s += 4; + libssh2_htonu32(s, filename_len); s += 4; + memcpy(s, filename, filename_len); s += filename_len; + if (open_type == LIBSSH2_SFTP_OPENFILE) { + libssh2_htonu32(s, flags); s += 4; + s += libssh2_sftp_attr2bin(s, &attrs); + } + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Sending %s open request", (open_type == LIBSSH2_SFTP_OPENFILE) ? "file" : "directory"); + if (packet_len != _libssh2_channel_write(channel, (char *)packet, + packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_OPEN or FXP_OPENDIR command", 0); LIBSSH2_FREE(session, packet); - + return NULL; + } + LIBSSH2_FREE(session, packet); + /* #warning "XXX - Looping on PACKET_EAGAIN (blocking) until fix is migrated up farther" */ - while ((rc = libssh2_sftp_packet_requirev(sftp, 2, fopen_responses, request_id, &data, &data_len)) == PACKET_EAGAIN) { - ; - } - if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); - return NULL; - } - - if (data[0] == SSH_FXP_STATUS) { - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Failed opening remote file", 0); - sftp->last_errno = libssh2_ntohu32(data + 5); - LIBSSH2_FREE(session, data); - return NULL; - } - - fp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE)); - if (!fp) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate new SFTP handle structure", 0); - LIBSSH2_FREE(session, data); - return NULL; - } - memset(fp, 0, sizeof(LIBSSH2_SFTP_HANDLE)); - fp->handle_type = (open_type == LIBSSH2_SFTP_OPENFILE) ? LIBSSH2_SFTP_HANDLE_FILE : LIBSSH2_SFTP_HANDLE_DIR; - - fp->handle_len = libssh2_ntohu32(data + 5); - if (fp->handle_len > 256) { - /* SFTP doesn't allow handles longer than 256 characters */ - fp->handle_len = 256; - } - fp->handle = LIBSSH2_ALLOC(session, fp->handle_len); - if (!fp->handle) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate space for SFTP file/dir handle", 0); - LIBSSH2_FREE(session, data); - LIBSSH2_FREE(session, fp); - return NULL; - } - memcpy(fp->handle, data + 9, fp->handle_len); + while ((rc = libssh2_sftp_packet_requirev(sftp, 2, fopen_responses, request_id, &data, &data_len)) == PACKET_EAGAIN) { + ; + } + if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + return NULL; + } + + if (data[0] == SSH_FXP_STATUS) { + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Failed opening remote file", 0); + sftp->last_errno = libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); - - /* Link the file and the sftp session together */ - fp->next = sftp->handles; - if (fp->next) { - fp->next->prev = fp; - } - fp->sftp = sftp; - - fp->u.file.offset = 0; - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Open command successful"); - return fp; + return NULL; + } + + fp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE)); + if (!fp) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate new SFTP handle structure", 0); + LIBSSH2_FREE(session, data); + return NULL; + } + memset(fp, 0, sizeof(LIBSSH2_SFTP_HANDLE)); + fp->handle_type = (open_type == LIBSSH2_SFTP_OPENFILE) ? LIBSSH2_SFTP_HANDLE_FILE : LIBSSH2_SFTP_HANDLE_DIR; + + fp->handle_len = libssh2_ntohu32(data + 5); + if (fp->handle_len > 256) { + /* SFTP doesn't allow handles longer than 256 characters */ + fp->handle_len = 256; + } + fp->handle = LIBSSH2_ALLOC(session, fp->handle_len); + if (!fp->handle) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate space for SFTP file/dir handle", 0); + LIBSSH2_FREE(session, data); + LIBSSH2_FREE(session, fp); + return NULL; + } + memcpy(fp->handle, data + 9, fp->handle_len); + LIBSSH2_FREE(session, data); + + /* Link the file and the sftp session together */ + fp->next = sftp->handles; + if (fp->next) { + fp->next->prev = fp; + } + fp->sftp = sftp; + + fp->u.file.offset = 0; + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Open command successful"); + return fp; } /* }}} */ @@ -1006,19 +1006,19 @@ LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_API ssize_t libssh2_sftp_readnb(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen) { - ssize_t rc; - LIBSSH2_CHANNEL *ch = handle->sftp->channel; - int bl = libssh2_channel_get_blocking(ch); - - /* set non-blocking */ - libssh2_channel_set_blocking(ch, 0); - - rc = _libssh2_sftp_read(handle, buffer, buffer_maxlen); - - /* restore state */ - libssh2_channel_set_blocking(ch, bl); - - return rc; + ssize_t rc; + LIBSSH2_CHANNEL *ch = handle->sftp->channel; + int bl = libssh2_channel_get_blocking(ch); + + /* set non-blocking */ + libssh2_channel_set_blocking(ch, 0); + + rc = _libssh2_sftp_read(handle, buffer, buffer_maxlen); + + /* restore state */ + libssh2_channel_set_blocking(ch, bl); + + return rc; } /* }}} */ @@ -1029,17 +1029,17 @@ LIBSSH2_API ssize_t libssh2_sftp_readnb(LIBSSH2_SFTP_HANDLE *handle, static int _libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs) { - LIBSSH2_SFTP *sftp = handle->sftp; - LIBSSH2_CHANNEL *channel = sftp->channel; - LIBSSH2_SESSION *session = channel->session; - LIBSSH2_SFTP_ATTRIBUTES attrs_dummy; - unsigned long data_len, request_id, filename_len, num_names; + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_ATTRIBUTES attrs_dummy; + unsigned long data_len, request_id, filename_len, num_names; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ - ssize_t packet_len = handle->handle_len + 13; - unsigned char *packet, *s, *data; - unsigned char read_responses[2] = { SSH_FXP_NAME, SSH_FXP_STATUS }; - int retcode; - + ssize_t packet_len = handle->handle_len + 13; + unsigned char *packet, *s, *data; + unsigned char read_responses[2] = { SSH_FXP_NAME, SSH_FXP_STATUS }; + int retcode; + if (sftp->readdir_state == sftp_readdir_idle) { if (handle->u.dir.names_left) { /* @@ -1137,70 +1137,70 @@ static int _libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size } retcode = libssh2_sftp_packet_requirev(sftp, 2, read_responses, request_id, &data, &data_len); - if (retcode == PACKET_EAGAIN) { - return PACKET_EAGAIN; - } - else if (retcode) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + if (retcode == PACKET_EAGAIN) { + return PACKET_EAGAIN; + } + else if (retcode) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); sftp->readdir_state = sftp_readdir_idle; - return -1; - } + return -1; + } - if (data[0] == SSH_FXP_STATUS) { - retcode = libssh2_ntohu32(data + 5); - LIBSSH2_FREE(session, data); - if (retcode == LIBSSH2_FX_EOF) { + if (data[0] == SSH_FXP_STATUS) { + retcode = libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if (retcode == LIBSSH2_FX_EOF) { sftp->readdir_state = sftp_readdir_idle; - return 0; - } else { - sftp->last_errno = retcode; - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + return 0; + } else { + sftp->last_errno = retcode; + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); sftp->readdir_state = sftp_readdir_idle; - return -1; - } - } + return -1; + } + } - num_names = libssh2_ntohu32(data + 5); - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%lu entries returned", num_names); - if (num_names <= 0) { - LIBSSH2_FREE(session, data); + num_names = libssh2_ntohu32(data + 5); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%lu entries returned", num_names); + if (num_names <= 0) { + LIBSSH2_FREE(session, data); sftp->readdir_state = sftp_readdir_idle; - return (num_names == 0) ? 0 : -1; - } + return (num_names == 0) ? 0 : -1; + } - if (num_names == 1) { - unsigned long real_filename_len = libssh2_ntohu32(data + 9); + if (num_names == 1) { + unsigned long real_filename_len = libssh2_ntohu32(data + 9); - filename_len = real_filename_len; - if (filename_len > buffer_maxlen) { - filename_len = buffer_maxlen; - } - memcpy(buffer, data + 13, filename_len); + filename_len = real_filename_len; + if (filename_len > buffer_maxlen) { + filename_len = buffer_maxlen; + } + memcpy(buffer, data + 13, filename_len); - /* The filename is not null terminated, make it so if possible */ - if (filename_len < buffer_maxlen) { - buffer[filename_len] = '\0'; - } + /* The filename is not null terminated, make it so if possible */ + if (filename_len < buffer_maxlen) { + buffer[filename_len] = '\0'; + } - if (attrs) { - memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); - libssh2_sftp_bin2attr(attrs, data + 13 + real_filename_len + + if (attrs) { + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + libssh2_sftp_bin2attr(attrs, data + 13 + real_filename_len + (4 + libssh2_ntohu32(data + 13 + real_filename_len))); - } - LIBSSH2_FREE(session, data); + } + LIBSSH2_FREE(session, data); sftp->readdir_state = sftp_readdir_idle; - return filename_len; - } + return filename_len; + } - handle->u.dir.names_left = num_names; - handle->u.dir.names_packet = data; - handle->u.dir.next_name = (char *)data + 9; + handle->u.dir.names_left = num_names; + handle->u.dir.names_packet = data; + handle->u.dir.next_name = (char *)data + 9; sftp->readdir_state = sftp_readdir_idle; - /* Be lazy, just use the name popping mechanism from the start of the function */ - return libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs); + /* Be lazy, just use the name popping mechanism from the start of the function */ + return libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs); } /* }}} */ @@ -1209,27 +1209,27 @@ static int _libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size */ /* libssh2_sftp_readdir - NB-SAFE */ LIBSSH2_API int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, - size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs) + size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs) { - int rc; - LIBSSH2_CHANNEL *ch = handle->sftp->channel; - int bl = libssh2_channel_get_blocking(ch); - - /* set blocking */ - libssh2_channel_set_blocking(ch, 1); - - rc = _libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs); - - /* restore state */ - libssh2_channel_set_blocking(ch, bl); - - if(rc < 0) { - /* precent accidental returning of other return codes since - this API does not support/provide those */ - return -1; - } - - return rc; + int rc; + LIBSSH2_CHANNEL *ch = handle->sftp->channel; + int bl = libssh2_channel_get_blocking(ch); + + /* set blocking */ + libssh2_channel_set_blocking(ch, 1); + + rc = _libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs); + + /* restore state */ + libssh2_channel_set_blocking(ch, bl); + + if(rc < 0) { + /* precent accidental returning of other return codes since + this API does not support/provide those */ + return -1; + } + + return rc; } /* }}} */ @@ -1238,21 +1238,21 @@ LIBSSH2_API int libssh2_sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, */ /* libssh2_sftp_readdirnb - NB-SAFE */ LIBSSH2_API int libssh2_sftp_readdirnb(LIBSSH2_SFTP_HANDLE *handle, char *buffer, - size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs) + size_t buffer_maxlen, LIBSSH2_SFTP_ATTRIBUTES *attrs) { - int rc; - LIBSSH2_CHANNEL *ch = handle->sftp->channel; - int bl = libssh2_channel_get_blocking(ch); - - /* set non-blocking */ - libssh2_channel_set_blocking(ch, 0); - - rc = _libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs); - - /* restore state */ - libssh2_channel_set_blocking(ch, bl); - - return rc; + int rc; + LIBSSH2_CHANNEL *ch = handle->sftp->channel; + int bl = libssh2_channel_get_blocking(ch); + + /* set non-blocking */ + libssh2_channel_set_blocking(ch, 0); + + rc = _libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs); + + /* restore state */ + libssh2_channel_set_blocking(ch, bl); + + return rc; } /* }}} */ @@ -1322,14 +1322,14 @@ static ssize_t _libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buff } rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len); - if (rc == PACKET_EAGAIN) { - return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + if (rc == PACKET_EAGAIN) { + return PACKET_EAGAIN; + } + else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); sftp->write_state = sftp_write_idle; - return -1; - } + return -1; + } sftp->write_state = sftp_write_idle; @@ -1405,66 +1405,66 @@ LIBSSH2_API ssize_t libssh2_sftp_writenb(LIBSSH2_SFTP_HANDLE *handle, /* libssh2_sftp_fstat_ex - NB-UNSAFE?? */ LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) { - LIBSSH2_SFTP *sftp = handle->sftp; - LIBSSH2_CHANNEL *channel = sftp->channel; - LIBSSH2_SESSION *session = channel->session; - unsigned long data_len, request_id; - ssize_t packet_len = handle->handle_len + 13 + (setstat ? libssh2_sftp_attrsize(attrs) : 0); - /* packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ - unsigned char *packet, *s, *data; - static const unsigned char fstat_responses[2] = { SSH_FXP_ATTRS, SSH_FXP_STATUS }; - int rc; - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Issuing %s command", setstat ? "set-stat" : "stat"); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FSTAT/FSETSTAT packet", 0); - return -1; - } - - libssh2_htonu32(s, packet_len - 4); s += 4; - *(s++) = setstat ? SSH_FXP_FSETSTAT : SSH_FXP_FSTAT; - request_id = sftp->request_id++; - libssh2_htonu32(s, request_id); s += 4; - libssh2_htonu32(s, handle->handle_len); s += 4; - memcpy(s, handle->handle, handle->handle_len); s += handle->handle_len; - if (setstat) { - s += libssh2_sftp_attr2bin(s, attrs); - } - - if (packet_len != libssh2_channel_write(channel, (char *)packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, setstat ? (char *)"Unable to send FXP_FSETSTAT" : (char *)"Unable to send FXP_FSTAT command", 0); - LIBSSH2_FREE(session, packet); - return -1; - } + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned long data_len, request_id; + ssize_t packet_len = handle->handle_len + 13 + (setstat ? libssh2_sftp_attrsize(attrs) : 0); + /* packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + unsigned char *packet, *s, *data; + static const unsigned char fstat_responses[2] = { SSH_FXP_ATTRS, SSH_FXP_STATUS }; + int rc; + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Issuing %s command", setstat ? "set-stat" : "stat"); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FSTAT/FSETSTAT packet", 0); + return -1; + } + + libssh2_htonu32(s, packet_len - 4); s += 4; + *(s++) = setstat ? SSH_FXP_FSETSTAT : SSH_FXP_FSTAT; + request_id = sftp->request_id++; + libssh2_htonu32(s, request_id); s += 4; + libssh2_htonu32(s, handle->handle_len); s += 4; + memcpy(s, handle->handle, handle->handle_len); s += handle->handle_len; + if (setstat) { + s += libssh2_sftp_attr2bin(s, attrs); + } + + if (packet_len != libssh2_channel_write(channel, (char *)packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, setstat ? (char *)"Unable to send FXP_FSETSTAT" : (char *)"Unable to send FXP_FSTAT command", 0); LIBSSH2_FREE(session, packet); - + return -1; + } + LIBSSH2_FREE(session, packet); + /* #warning "XXX - Looping on PACKET_EAGAIN (blocking) until fix is migrated up farther" */ - while ((rc = libssh2_sftp_packet_requirev(sftp, 2, fstat_responses, request_id, &data, &data_len)) == PACKET_EAGAIN) { - ; - } - if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); - return -1; + while ((rc = libssh2_sftp_packet_requirev(sftp, 2, fstat_responses, request_id, &data, &data_len)) == PACKET_EAGAIN) { + ; + } + if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + return -1; + } + + if (data[0] == SSH_FXP_STATUS) { + int retcode; + + retcode = libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + return -1; } - - if (data[0] == SSH_FXP_STATUS) { - int retcode; - - retcode = libssh2_ntohu32(data + 5); - LIBSSH2_FREE(session, data); - if (retcode == LIBSSH2_FX_OK) { - return 0; - } else { - sftp->last_errno = retcode; - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); - return -1; - } - } - - libssh2_sftp_bin2attr(attrs, data + 5); - - return 0; + } + + libssh2_sftp_bin2attr(attrs, data + 5); + + return 0; } /* }}} */ @@ -1496,69 +1496,69 @@ LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle) /* libssh2_sftp_close_handle - NB-UNSAFE?? */ LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle) { - LIBSSH2_SFTP *sftp = handle->sftp; - LIBSSH2_CHANNEL *channel = sftp->channel; - LIBSSH2_SESSION *session = channel->session; - unsigned long data_len, retcode, request_id; - ssize_t packet_len = handle->handle_len + 13; /* packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ - unsigned char *packet, *s, *data; - int rc; - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Closing handle"); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_CLOSE packet", 0); - return -1; - } - - libssh2_htonu32(s, packet_len - 4); s += 4; - *(s++) = SSH_FXP_CLOSE; - request_id = sftp->request_id++; - libssh2_htonu32(s, request_id); s += 4; - libssh2_htonu32(s, handle->handle_len); s += 4; - memcpy(s, handle->handle, handle->handle_len); s += handle->handle_len; - - if (packet_len != libssh2_channel_write(channel, (char *)packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_CLOSE command", 0); - LIBSSH2_FREE(session, packet); - return -1; - } + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned long data_len, retcode, request_id; + ssize_t packet_len = handle->handle_len + 13; /* packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + unsigned char *packet, *s, *data; + int rc; + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Closing handle"); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_CLOSE packet", 0); + return -1; + } + + libssh2_htonu32(s, packet_len - 4); s += 4; + *(s++) = SSH_FXP_CLOSE; + request_id = sftp->request_id++; + libssh2_htonu32(s, request_id); s += 4; + libssh2_htonu32(s, handle->handle_len); s += 4; + memcpy(s, handle->handle, handle->handle_len); s += handle->handle_len; + + if (packet_len != libssh2_channel_write(channel, (char *)packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_CLOSE command", 0); LIBSSH2_FREE(session, packet); - + return -1; + } + LIBSSH2_FREE(session, packet); + /* #warning "XXX - Looping on PACKET_EAGAIN (blocking) until fix is migrated up farther" */ - while ((rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len)) == PACKET_EAGAIN) { - ; - } - if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); - return -1; - } - - retcode = libssh2_ntohu32(data + 5); - LIBSSH2_FREE(session, data); - - if (retcode != LIBSSH2_FX_OK) { - sftp->last_errno = retcode; - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); - return -1; - } - - if (handle == sftp->handles) { - sftp->handles = handle->next; - } - if (handle->next) { - handle->next->prev = NULL; - } - - if ((handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR) && - handle->u.dir.names_left) { - LIBSSH2_FREE(session, handle->u.dir.names_packet); - } - - LIBSSH2_FREE(session, handle->handle); - LIBSSH2_FREE(session, handle); - - return 0; + while ((rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len)) == PACKET_EAGAIN) { + ; + } + if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + return -1; + } + + retcode = libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode != LIBSSH2_FX_OK) { + sftp->last_errno = retcode; + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + return -1; + } + + if (handle == sftp->handles) { + sftp->handles = handle->next; + } + if (handle->next) { + handle->next->prev = NULL; + } + + if ((handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR) && + handle->u.dir.names_left) { + LIBSSH2_FREE(session, handle->u.dir.names_packet); + } + + LIBSSH2_FREE(session, handle->handle); + LIBSSH2_FREE(session, handle); + + return 0; } /* }}} */ @@ -1572,54 +1572,54 @@ LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle) /* libssh2_sftp_unlink_ex - NB-UNSAFE?? */ LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len) { - LIBSSH2_CHANNEL *channel = sftp->channel; - LIBSSH2_SESSION *session = channel->session; - unsigned long data_len, retcode, request_id; - ssize_t packet_len = filename_len + 13; /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) */ - unsigned char *packet, *s, *data; - int rc; - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Unlinking %s", filename); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_REMOVE packet", 0); - return -1; - } - - libssh2_htonu32(s, packet_len - 4); s += 4; - *(s++) = SSH_FXP_REMOVE; - request_id = sftp->request_id++; - libssh2_htonu32(s, request_id); s += 4; - libssh2_htonu32(s, filename_len); s += 4; - memcpy(s, filename, filename_len); s += filename_len; - - if (packet_len != libssh2_channel_write(channel, (char *)packet, - packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_REMOVE command", 0); - LIBSSH2_FREE(session, packet); - return -1; - } + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned long data_len, retcode, request_id; + ssize_t packet_len = filename_len + 13; /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) */ + unsigned char *packet, *s, *data; + int rc; + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Unlinking %s", filename); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_REMOVE packet", 0); + return -1; + } + + libssh2_htonu32(s, packet_len - 4); s += 4; + *(s++) = SSH_FXP_REMOVE; + request_id = sftp->request_id++; + libssh2_htonu32(s, request_id); s += 4; + libssh2_htonu32(s, filename_len); s += 4; + memcpy(s, filename, filename_len); s += filename_len; + + if (packet_len != libssh2_channel_write(channel, (char *)packet, + packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_REMOVE command", 0); LIBSSH2_FREE(session, packet); - + return -1; + } + LIBSSH2_FREE(session, packet); + /* #warning "XXX - Looping on PACKET_EAGAIN (blocking) until fix is migrated up farther" */ - while ((rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len)) == PACKET_EAGAIN) { - ; - } - if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); - return -1; - } - - retcode = libssh2_ntohu32(data + 5); - LIBSSH2_FREE(session, data); - - if (retcode == LIBSSH2_FX_OK) { - return 0; - } else { - sftp->last_errno = retcode; - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); - return -1; - } + while ((rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len)) == PACKET_EAGAIN) { + ; + } + if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + return -1; + } + + retcode = libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + return -1; + } } /* }}} */ @@ -1631,81 +1631,81 @@ LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_f const char *dest_filename, unsigned int dest_filename_len, long flags) { - LIBSSH2_CHANNEL *channel = sftp->channel; - LIBSSH2_SESSION *session = channel->session; - unsigned long data_len, retcode = -1, request_id; - ssize_t packet_len = source_filename_len + dest_filename_len + 17 + (sftp->version >= 5 ? 4 : 0); - /* packet_len(4) + packet_type(1) + request_id(4) + - source_filename_len(4) + dest_filename_len(4) + flags(4){SFTP5+) */ - unsigned char *packet, *s, *data; - int rc; - - if (sftp->version < 2) { - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Server does not support RENAME", 0); - return -1; - } - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Renaming %s to %s", source_filename, dest_filename); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_RENAME packet", 0); - return -1; - } - - libssh2_htonu32(s, packet_len - 4); s += 4; - *(s++) = SSH_FXP_RENAME; - request_id = sftp->request_id++; - libssh2_htonu32(s, request_id); s += 4; - libssh2_htonu32(s, source_filename_len); s += 4; - memcpy(s, source_filename, source_filename_len); s += source_filename_len; - libssh2_htonu32(s, dest_filename_len); s += 4; - memcpy(s, dest_filename, dest_filename_len); s += dest_filename_len; - - if (sftp->version >= 5) { - libssh2_htonu32(s, flags); s += 4; - } - - if (packet_len != libssh2_channel_write(channel, (char *)packet, - s - packet)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_RENAME command", 0); - LIBSSH2_FREE(session, packet); - return -1; - } + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned long data_len, retcode = -1, request_id; + ssize_t packet_len = source_filename_len + dest_filename_len + 17 + (sftp->version >= 5 ? 4 : 0); + /* packet_len(4) + packet_type(1) + request_id(4) + + source_filename_len(4) + dest_filename_len(4) + flags(4){SFTP5+) */ + unsigned char *packet, *s, *data; + int rc; + + if (sftp->version < 2) { + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Server does not support RENAME", 0); + return -1; + } + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Renaming %s to %s", source_filename, dest_filename); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_RENAME packet", 0); + return -1; + } + + libssh2_htonu32(s, packet_len - 4); s += 4; + *(s++) = SSH_FXP_RENAME; + request_id = sftp->request_id++; + libssh2_htonu32(s, request_id); s += 4; + libssh2_htonu32(s, source_filename_len); s += 4; + memcpy(s, source_filename, source_filename_len); s += source_filename_len; + libssh2_htonu32(s, dest_filename_len); s += 4; + memcpy(s, dest_filename, dest_filename_len); s += dest_filename_len; + + if (sftp->version >= 5) { + libssh2_htonu32(s, flags); s += 4; + } + + if (packet_len != libssh2_channel_write(channel, (char *)packet, + s - packet)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_RENAME command", 0); LIBSSH2_FREE(session, packet); - + return -1; + } + LIBSSH2_FREE(session, packet); + /* #warning "XXX - Looping on PACKET_EAGAIN (blocking) until fix is migrated up farther" */ - while ((rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len)) == PACKET_EAGAIN) { - ; - } - if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); - return -1; - } - - retcode = libssh2_ntohu32(data + 5); - LIBSSH2_FREE(session, data); - - switch (retcode) { - case LIBSSH2_FX_OK: - retcode = 0; - break; - case LIBSSH2_FX_FILE_ALREADY_EXISTS: - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "File already exists and SSH_FXP_RENAME_OVERWRITE not specified", 0); - sftp->last_errno = retcode; - retcode = -1; - break; - case LIBSSH2_FX_OP_UNSUPPORTED: - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Operation Not Supported", 0); - sftp->last_errno = retcode; - retcode = -1; - break; - default: - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); - sftp->last_errno = retcode; - retcode = -1; - } - - return retcode; + while ((rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len)) == PACKET_EAGAIN) { + ; + } + if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + return -1; + } + + retcode = libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + switch (retcode) { + case LIBSSH2_FX_OK: + retcode = 0; + break; + case LIBSSH2_FX_FILE_ALREADY_EXISTS: + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "File already exists and SSH_FXP_RENAME_OVERWRITE not specified", 0); + sftp->last_errno = retcode; + retcode = -1; + break; + case LIBSSH2_FX_OP_UNSUPPORTED: + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Operation Not Supported", 0); + sftp->last_errno = retcode; + retcode = -1; + break; + default: + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + sftp->last_errno = retcode; + retcode = -1; + } + + return retcode; } /* }}} */ @@ -1717,9 +1717,9 @@ static int _libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; - LIBSSH2_SFTP_ATTRIBUTES attrs = { - LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 - }; + LIBSSH2_SFTP_ATTRIBUTES attrs = { + LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 + }; unsigned long data_len, retcode, request_id; ssize_t packet_len = path_len + 13 + libssh2_sftp_attrsize(&attrs); /* packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ @@ -1777,14 +1777,14 @@ static int _libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned } rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len); - if (rc == PACKET_EAGAIN) { - return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + if (rc == PACKET_EAGAIN) { + return PACKET_EAGAIN; + } + else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); sftp->mkdir_state = sftp_mkdir_idle; - return -1; - } + return -1; + } sftp->mkdir_state = sftp_mkdir_idle; @@ -1857,53 +1857,53 @@ LIBSSH2_API int libssh2_sftp_mkdirnb_ex(LIBSSH2_SFTP *sftp, const char *path, un /* libssh2_sftp_rmdir_ex - NB-UNSAFE?? */ LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len) { - LIBSSH2_CHANNEL *channel = sftp->channel; - LIBSSH2_SESSION *session = channel->session; - unsigned long data_len, retcode, request_id; - ssize_t packet_len = path_len + 13; /* packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ - unsigned char *packet, *s, *data; - int rc; - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Removing directory: %s", path); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_MKDIR packet", 0); - return -1; - } - - libssh2_htonu32(s, packet_len - 4); s += 4; - *(s++) = SSH_FXP_RMDIR; - request_id = sftp->request_id++; - libssh2_htonu32(s, request_id); s += 4; - libssh2_htonu32(s, path_len); s += 4; - memcpy(s, path, path_len); s += path_len; - - if (packet_len != libssh2_channel_write(channel, (char *)packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_MKDIR command", 0); - LIBSSH2_FREE(session, packet); - return -1; - } + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned long data_len, retcode, request_id; + ssize_t packet_len = path_len + 13; /* packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + unsigned char *packet, *s, *data; + int rc; + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Removing directory: %s", path); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_MKDIR packet", 0); + return -1; + } + + libssh2_htonu32(s, packet_len - 4); s += 4; + *(s++) = SSH_FXP_RMDIR; + request_id = sftp->request_id++; + libssh2_htonu32(s, request_id); s += 4; + libssh2_htonu32(s, path_len); s += 4; + memcpy(s, path, path_len); s += path_len; + + if (packet_len != libssh2_channel_write(channel, (char *)packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_MKDIR command", 0); LIBSSH2_FREE(session, packet); - + return -1; + } + LIBSSH2_FREE(session, packet); + /* #warning "XXX - Looping on PACKET_EAGAIN (blocking) until fix is migrated up farther" */ - while ((rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len)) == PACKET_EAGAIN) { - ; - } - if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); - return -1; - } - - retcode = libssh2_ntohu32(data + 5); - LIBSSH2_FREE(session, data); - - if (retcode == LIBSSH2_FX_OK) { - return 0; - } else { - sftp->last_errno = retcode; - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); - return -1; - } + while ((rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len)) == PACKET_EAGAIN) { + ; + } + if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + return -1; + } + + retcode = libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + return -1; + } } /* }}} */ @@ -1913,78 +1913,78 @@ LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsi /* libssh2_sftp_stat_ex - NB-UNSAFE?? */ LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, int stat_type, LIBSSH2_SFTP_ATTRIBUTES *attrs) { - LIBSSH2_CHANNEL *channel = sftp->channel; - LIBSSH2_SESSION *session = channel->session; - unsigned long data_len, request_id; - ssize_t packet_len = path_len + 13 + ((stat_type == LIBSSH2_SFTP_SETSTAT) ? libssh2_sftp_attrsize(attrs) : 0); - /* packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ - unsigned char *packet, *s, *data; - static const unsigned char stat_responses[2] = { SSH_FXP_ATTRS, SSH_FXP_STATUS }; - int rc; - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%s %s", (stat_type == LIBSSH2_SFTP_SETSTAT) ? "Set-statting" : (stat_type == LIBSSH2_SFTP_LSTAT ? "LStatting" : "Statting"), path); - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_MKDIR packet", 0); - return -1; - } - - libssh2_htonu32(s, packet_len - 4); s += 4; - switch (stat_type) { - case LIBSSH2_SFTP_SETSTAT: - *(s++) = SSH_FXP_SETSTAT; - break; - case LIBSSH2_SFTP_LSTAT: - *(s++) = SSH_FXP_LSTAT; - break; - case LIBSSH2_SFTP_STAT: - default: - *(s++) = SSH_FXP_STAT; - } - request_id = sftp->request_id++; - libssh2_htonu32(s, request_id); s += 4; - libssh2_htonu32(s, path_len); s += 4; - memcpy(s, path, path_len); s += path_len; - if (stat_type == LIBSSH2_SFTP_SETSTAT) { - s += libssh2_sftp_attr2bin(s, attrs); - } - - if (packet_len != libssh2_channel_write(channel, (char *)packet, - packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send STAT/LSTAT/SETSTAT command", 0); - LIBSSH2_FREE(session, packet); - return -1; - } + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned long data_len, request_id; + ssize_t packet_len = path_len + 13 + ((stat_type == LIBSSH2_SFTP_SETSTAT) ? libssh2_sftp_attrsize(attrs) : 0); + /* packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + unsigned char *packet, *s, *data; + static const unsigned char stat_responses[2] = { SSH_FXP_ATTRS, SSH_FXP_STATUS }; + int rc; + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%s %s", (stat_type == LIBSSH2_SFTP_SETSTAT) ? "Set-statting" : (stat_type == LIBSSH2_SFTP_LSTAT ? "LStatting" : "Statting"), path); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_MKDIR packet", 0); + return -1; + } + + libssh2_htonu32(s, packet_len - 4); s += 4; + switch (stat_type) { + case LIBSSH2_SFTP_SETSTAT: + *(s++) = SSH_FXP_SETSTAT; + break; + case LIBSSH2_SFTP_LSTAT: + *(s++) = SSH_FXP_LSTAT; + break; + case LIBSSH2_SFTP_STAT: + default: + *(s++) = SSH_FXP_STAT; + } + request_id = sftp->request_id++; + libssh2_htonu32(s, request_id); s += 4; + libssh2_htonu32(s, path_len); s += 4; + memcpy(s, path, path_len); s += path_len; + if (stat_type == LIBSSH2_SFTP_SETSTAT) { + s += libssh2_sftp_attr2bin(s, attrs); + } + + if (packet_len != libssh2_channel_write(channel, (char *)packet, + packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send STAT/LSTAT/SETSTAT command", 0); LIBSSH2_FREE(session, packet); - + return -1; + } + LIBSSH2_FREE(session, packet); + /* #warning "XXX - Looping on PACKET_EAGAIN (blocking) until fix is migrated up farther" */ - while ((rc = libssh2_sftp_packet_requirev(sftp, 2, stat_responses, request_id, &data, &data_len)) == PACKET_EAGAIN) { - ; - } - if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); - return -1; - } - - if (data[0] == SSH_FXP_STATUS) { - int retcode; - - retcode = libssh2_ntohu32(data + 5); - LIBSSH2_FREE(session, data); - if (retcode == LIBSSH2_FX_OK) { - return 0; - } else { - sftp->last_errno = retcode; - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); - return -1; - } - } - - memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); - libssh2_sftp_bin2attr(attrs, data + 5); + while ((rc = libssh2_sftp_packet_requirev(sftp, 2, stat_responses, request_id, &data, &data_len)) == PACKET_EAGAIN) { + ; + } + if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + return -1; + } + + if (data[0] == SSH_FXP_STATUS) { + int retcode; + + retcode = libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); - - return 0; + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + return -1; + } + } + + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + libssh2_sftp_bin2attr(attrs, data + 5); + LIBSSH2_FREE(session, data); + + return 0; } /* }}} */ @@ -1994,96 +1994,96 @@ LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, unsig /* libssh2_sftp_symlink_ex - NB-UNSAFE?? */ LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, char *target, unsigned int target_len, int link_type) { - LIBSSH2_CHANNEL *channel = sftp->channel; - LIBSSH2_SESSION *session = channel->session; - unsigned long data_len, request_id, link_len; - ssize_t packet_len = path_len + 13 + ((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0); - /* packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ - unsigned char *packet, *s, *data; - static const unsigned char link_responses[2] = { SSH_FXP_NAME, SSH_FXP_STATUS }; - int rc; - - if ((sftp->version < 3) && - (link_type != LIBSSH2_SFTP_REALPATH)) { - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Server does not support SYMLINK or READLINK", 0); - return -1; - } - - s = packet = LIBSSH2_ALLOC(session, packet_len); - if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for SYMLINK/READLINK/REALPATH packet", 0); - return -1; - } - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%s %s on %s", (link_type == LIBSSH2_SFTP_SYMLINK) ? "Creating" : "Reading", - (link_type == LIBSSH2_SFTP_REALPATH) ? "realpath" : "symlink", path); - libssh2_htonu32(s, packet_len - 4); s += 4; - switch (link_type) { - case LIBSSH2_SFTP_REALPATH: - *(s++) = SSH_FXP_REALPATH; - break; - case LIBSSH2_SFTP_SYMLINK: - *(s++) = SSH_FXP_SYMLINK; - break; - case LIBSSH2_SFTP_READLINK: - default: - *(s++) = SSH_FXP_READLINK; - } - request_id = sftp->request_id++; - libssh2_htonu32(s, request_id); s += 4; - libssh2_htonu32(s, path_len); s += 4; - memcpy(s, path, path_len); s += path_len; - if (link_type == LIBSSH2_SFTP_SYMLINK) { - libssh2_htonu32(s, target_len); s += 4; - memcpy(s, target, target_len); s += target_len; - } - - if (packet_len != libssh2_channel_write(channel, (char *)packet, - packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send SYMLINK/READLINK command", 0); - LIBSSH2_FREE(session, packet); - return -1; - } + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned long data_len, request_id, link_len; + ssize_t packet_len = path_len + 13 + ((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0); + /* packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + unsigned char *packet, *s, *data; + static const unsigned char link_responses[2] = { SSH_FXP_NAME, SSH_FXP_STATUS }; + int rc; + + if ((sftp->version < 3) && + (link_type != LIBSSH2_SFTP_REALPATH)) { + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Server does not support SYMLINK or READLINK", 0); + return -1; + } + + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for SYMLINK/READLINK/REALPATH packet", 0); + return -1; + } + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%s %s on %s", (link_type == LIBSSH2_SFTP_SYMLINK) ? "Creating" : "Reading", + (link_type == LIBSSH2_SFTP_REALPATH) ? "realpath" : "symlink", path); + libssh2_htonu32(s, packet_len - 4); s += 4; + switch (link_type) { + case LIBSSH2_SFTP_REALPATH: + *(s++) = SSH_FXP_REALPATH; + break; + case LIBSSH2_SFTP_SYMLINK: + *(s++) = SSH_FXP_SYMLINK; + break; + case LIBSSH2_SFTP_READLINK: + default: + *(s++) = SSH_FXP_READLINK; + } + request_id = sftp->request_id++; + libssh2_htonu32(s, request_id); s += 4; + libssh2_htonu32(s, path_len); s += 4; + memcpy(s, path, path_len); s += path_len; + if (link_type == LIBSSH2_SFTP_SYMLINK) { + libssh2_htonu32(s, target_len); s += 4; + memcpy(s, target, target_len); s += target_len; + } + + if (packet_len != libssh2_channel_write(channel, (char *)packet, + packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send SYMLINK/READLINK command", 0); LIBSSH2_FREE(session, packet); - + return -1; + } + LIBSSH2_FREE(session, packet); + /* #warning "XXX - Looping on PACKET_EAGAIN (blocking) until fix is migrated up farther" */ - while ((rc = libssh2_sftp_packet_requirev(sftp, 2, link_responses, request_id, &data, &data_len)) == PACKET_EAGAIN) { - ; - } - if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); - return -1; - } - - if (data[0] == SSH_FXP_STATUS) { - int retcode; - - retcode = libssh2_ntohu32(data + 5); - LIBSSH2_FREE(session, data); - if (retcode == LIBSSH2_FX_OK) { - return 0; - } else { - sftp->last_errno = retcode; - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); - return -1; - } - } - - if (libssh2_ntohu32(data + 5) < 1) { - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Invalid READLINK/REALPATH response, no name entries", 0); - LIBSSH2_FREE(session, data); - return -1; - } - - link_len = libssh2_ntohu32(data + 9); - if (link_len >= target_len) { - link_len = target_len - 1; - } - memcpy(target, data + 13, link_len); - target[link_len] = 0; + while ((rc = libssh2_sftp_packet_requirev(sftp, 2, link_responses, request_id, &data, &data_len)) == PACKET_EAGAIN) { + ; + } + if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + return -1; + } + + if (data[0] == SSH_FXP_STATUS) { + int retcode; + + retcode = libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); - - return link_len; + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + return -1; + } + } + + if (libssh2_ntohu32(data + 5) < 1) { + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Invalid READLINK/REALPATH response, no name entries", 0); + LIBSSH2_FREE(session, data); + return -1; + } + + link_len = libssh2_ntohu32(data + 9); + if (link_len >= target_len) { + link_len = target_len - 1; + } + memcpy(target, data + 13, link_len); + target[link_len] = 0; + LIBSSH2_FREE(session, data); + + return link_len; } /* }}} */ @@ -2103,7 +2103,7 @@ LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp) */ /* libssh2_sftp_set_blocking - NB-SAFE */ LIBSSH2_API void libssh2_sftp_set_blocking(LIBSSH2_SFTP *session, int blocking) { - libssh2_channel_set_blocking(session->channel, blocking); + libssh2_channel_set_blocking(session->channel, blocking); } /* }}} */ @@ -2113,7 +2113,7 @@ LIBSSH2_API void libssh2_sftp_set_blocking(LIBSSH2_SFTP *session, int blocking) */ /* libssh2_sftp_get_blocking - NB-SAFE */ LIBSSH2_API int libssh2_sftp_get_blocking(LIBSSH2_SFTP *session) { - return libssh2_channel_get_blocking(session->channel); + return libssh2_channel_get_blocking(session->channel); } /* }}} */ diff --git a/src/transport.c b/src/transport.c index ebac835..fa0478d 100644 --- a/src/transport.c +++ b/src/transport.c @@ -49,8 +49,8 @@ #ifdef LIBSSH2DEBUG #define UNPRINTABLE_CHAR '.' static void debugdump(LIBSSH2_SESSION *session, - const char *desc, unsigned char *ptr, - unsigned long size) + const char *desc, unsigned char *ptr, + unsigned long size) { size_t i; size_t c; @@ -58,8 +58,8 @@ static void debugdump(LIBSSH2_SESSION *session, unsigned int width=0x10; if(!(session->showmask & (1<< LIBSSH2_DBG_TRANS))) { - /* not asked for, bail out */ - return; + /* not asked for, bail out */ + return; } fprintf(stream, "=> %s (%d bytes)\n", desc, (int)size); @@ -70,16 +70,16 @@ static void debugdump(LIBSSH2_SESSION *session, /* hex not disabled, show it */ for(c = 0; c < width; c++) { - if(i+c < size) - fprintf(stream, "%02x ", ptr[i+c]); - else - fputs(" ", stream); + if(i+c < size) + fprintf(stream, "%02x ", ptr[i+c]); + else + fputs(" ", stream); } for(c = 0; (c < width) && (i+c < size); c++) { - fprintf(stream, "%c", - (ptr[i+c]>=0x20) && - (ptr[i+c]<0x80)?ptr[i+c]:UNPRINTABLE_CHAR); + fprintf(stream, "%c", + (ptr[i+c]>=0x20) && + (ptr[i+c]<0x80)?ptr[i+c]:UNPRINTABLE_CHAR); } fputc('\n', stream); /* newline */ } @@ -98,32 +98,32 @@ static void debugdump(LIBSSH2_SESSION *session, static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source, unsigned char *dest, int len) { - struct transportpacket *p = &session->packet; - int blocksize = session->remote.crypt->blocksize; - - /* if we get called with a len that isn't an even number of blocksizes - we risk losing those extra bytes */ - assert((len % blocksize) == 0); - - while(len >= blocksize) { - if (session->remote.crypt->crypt(session, source, - &session->remote.crypt_abstract)) { - libssh2_error(session, LIBSSH2_ERROR_DECRYPT, - (char *)"Error decrypting packet", 0); - LIBSSH2_FREE(session, p->payload); - return PACKET_FAIL; - } - - /* if the crypt() function would write to a given address it - wouldn't have to memcpy() and we could avoid this memcpy() - too */ - memcpy(dest, source, blocksize); - - len -= blocksize; /* less bytes left */ - dest += blocksize; /* advance write pointer */ - source += blocksize; /* advance read pointer */ + struct transportpacket *p = &session->packet; + int blocksize = session->remote.crypt->blocksize; + + /* if we get called with a len that isn't an even number of blocksizes + we risk losing those extra bytes */ + assert((len % blocksize) == 0); + + while(len >= blocksize) { + if (session->remote.crypt->crypt(session, source, + &session->remote.crypt_abstract)) { + libssh2_error(session, LIBSSH2_ERROR_DECRYPT, + (char *)"Error decrypting packet", 0); + LIBSSH2_FREE(session, p->payload); + return PACKET_FAIL; } - return PACKET_NONE; /* all is fine */ + + /* if the crypt() function would write to a given address it + wouldn't have to memcpy() and we could avoid this memcpy() + too */ + memcpy(dest, source, blocksize); + + len -= blocksize; /* less bytes left */ + dest += blocksize; /* advance write pointer */ + source += blocksize; /* advance read pointer */ + } + return PACKET_NONE; /* all is fine */ } /* @@ -133,97 +133,97 @@ static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source, static libssh2pack_t fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */) { - unsigned char macbuf[MAX_MACSIZE]; - struct transportpacket *p = &session->packet; - int payload_len = p->packet_length-1; - libssh2pack_t packet_type; - int macstate = LIBSSH2_MAC_CONFIRMED; - - if(encrypted) { - - /* Calculate MAC hash */ - session->remote.mac->hash(session, - macbuf, /* store hash here */ - session->remote.seqno, - p->init, 5, - p->payload, payload_len, - &session->remote.mac_abstract); - - /* Compare the calculated hash with the MAC we just read from - * the network. The read one is at the very end of the payload - * buffer. Note that 'payload_len' here is the packet_length - * field which includes the padding but not the MAC. + unsigned char macbuf[MAX_MACSIZE]; + struct transportpacket *p = &session->packet; + int payload_len = p->packet_length-1; + libssh2pack_t packet_type; + int macstate = LIBSSH2_MAC_CONFIRMED; + + if(encrypted) { + + /* Calculate MAC hash */ + session->remote.mac->hash(session, + macbuf, /* store hash here */ + session->remote.seqno, + p->init, 5, + p->payload, payload_len, + &session->remote.mac_abstract); + + /* Compare the calculated hash with the MAC we just read from + * the network. The read one is at the very end of the payload + * buffer. Note that 'payload_len' here is the packet_length + * field which includes the padding but not the MAC. + */ + if(memcmp(macbuf, p->payload + payload_len, + session->remote.mac->mac_len)) { + macstate = LIBSSH2_MAC_INVALID; + } + } + + session->remote.seqno++; + + /* ignore the padding */ + payload_len -= p->padding_length; + + /* Check for and deal with decompression */ + if (session->remote.comp && + strcmp(session->remote.comp->name, "none")) { + unsigned char *data; + unsigned long data_len; + int free_payload = 1; + + if (session->remote.comp->comp(session, 0, + &data, &data_len, + LIBSSH2_PACKET_MAXDECOMP, + &free_payload, + p->payload, payload_len, + &session->remote.comp_abstract)) { + LIBSSH2_FREE(session, p->payload); + return PACKET_FAIL; + } + + if (free_payload) { + LIBSSH2_FREE(session, p->payload); + p->payload = data; + payload_len = data_len; + } + else { + if (data == p->payload) { + /* It's not to be freed, because the + * compression layer reused payload, So let's + * do the same! */ - if(memcmp(macbuf, p->payload + payload_len, - session->remote.mac->mac_len)) { - macstate = LIBSSH2_MAC_INVALID; + payload_len = data_len; + } + else { + /* No comp_method actually lets this happen, + * but let's prepare for the future */ + + LIBSSH2_FREE(session, p->payload); + + /* We need a freeable struct otherwise the + * brigade won't know what to do with it */ + p->payload = LIBSSH2_ALLOC(session, data_len); + if (!p->payload) { + libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + (char *)"Unable to allocate memory for copy of uncompressed data", 0); + return PACKET_ENOMEM; } + memcpy(p->payload, data, data_len); + payload_len = data_len; + } } - - session->remote.seqno++; - - /* ignore the padding */ - payload_len -= p->padding_length; - - /* Check for and deal with decompression */ - if (session->remote.comp && - strcmp(session->remote.comp->name, "none")) { - unsigned char *data; - unsigned long data_len; - int free_payload = 1; - - if (session->remote.comp->comp(session, 0, - &data, &data_len, - LIBSSH2_PACKET_MAXDECOMP, - &free_payload, - p->payload, payload_len, - &session->remote.comp_abstract)) { - LIBSSH2_FREE(session, p->payload); - return PACKET_FAIL; - } - - if (free_payload) { - LIBSSH2_FREE(session, p->payload); - p->payload = data; - payload_len = data_len; - } - else { - if (data == p->payload) { - /* It's not to be freed, because the - * compression layer reused payload, So let's - * do the same! - */ - payload_len = data_len; - } - else { - /* No comp_method actually lets this happen, - * but let's prepare for the future */ - - LIBSSH2_FREE(session, p->payload); - - /* We need a freeable struct otherwise the - * brigade won't know what to do with it */ - p->payload = LIBSSH2_ALLOC(session, data_len); - if (!p->payload) { - libssh2_error(session, - LIBSSH2_ERROR_ALLOC, - (char *)"Unable to allocate memory for copy of uncompressed data", 0); - return PACKET_ENOMEM; - } - memcpy(p->payload, data, data_len); - payload_len = data_len; - } - } - } - - packet_type = p->payload[0]; - - debugdump(session, "libssh2_packet_read() plain", - p->payload, payload_len); - if (libssh2_packet_add(session, p->payload, payload_len, macstate) < 0) - return PACKET_FAIL; - - return packet_type; + } + + packet_type = p->payload[0]; + + debugdump(session, "libssh2_packet_read() plain", + p->payload, payload_len); + if (libssh2_packet_add(session, p->payload, payload_len, macstate) < 0) + return PACKET_FAIL; + + return packet_type; } @@ -244,258 +244,258 @@ static libssh2pack_t fullpacket(LIBSSH2_SESSION *session, libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) { - libssh2pack_t rc; - struct transportpacket *p = &session->packet; - int remainbuf; - int remainpack; - int numbytes; - int numdecrypt; - unsigned char block[MAX_BLOCKSIZE]; - int blocksize; - int minimum; - int encrypted = 1; - - do { - - if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { - return PACKET_NONE; + libssh2pack_t rc; + struct transportpacket *p = &session->packet; + int remainbuf; + int remainpack; + int numbytes; + int numdecrypt; + unsigned char block[MAX_BLOCKSIZE]; + int blocksize; + int minimum; + int encrypted = 1; + + do { + + if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { + return PACKET_NONE; + } + + if (session->state & LIBSSH2_STATE_NEWKEYS) { + blocksize = session->remote.crypt->blocksize; + } + else { + encrypted = 0; /* not encrypted */ + blocksize = 5; /* not strictly true, but we can use 5 + here to make the checks below work + fine still */ + } + minimum = p->total_num ? p->total_num - p->data_num : blocksize; + + /* read/use a whole big chunk into a temporary area stored in + the LIBSSH2_SESSION struct. We will decrypt data from that + buffer into the packet buffer so this temp one doesn't have + to be able to keep a whole SSH packet, just be large enough + so that we can read big chunks from the network layer. */ + + /* how much data there is remaining in the buffer to deal with + before we should read more from the network */ + remainbuf = p->writeidx - p->readidx; + + /* if remainbuf turns negative we have a bad internal error */ + assert(remainbuf >= 0); + + while(remainbuf < minimum) { + /* While there is too little data to deal with, read + more */ + ssize_t nread; + + /* move any remainder to the start of the buffer so + that we can do a full refill */ + if(remainbuf) { + memmove(p->buf, &p->buf[p->readidx], + remainbuf); + p->readidx = 0; + p->writeidx = remainbuf; + } + else { + /* nothing to move, just zero the indexes */ + p->readidx = p->writeidx = 0; + } + + /* now read a big chunk from the network into the temp + buffer */ + nread = recv(session->socket_fd, &p->buf[remainbuf], + PACKETBUFSIZE-remainbuf, + LIBSSH2_SOCKET_RECV_FLAGS(session)); + if (nread <= 0) { + /* check if this is due to EAGAIN and return + the special return code if so, error out + normally otherwise */ + if(errno == EAGAIN) { + return PACKET_EAGAIN; } - - if (session->state & LIBSSH2_STATE_NEWKEYS) { - blocksize = session->remote.crypt->blocksize; + return PACKET_FAIL; + } + debugdump(session, "libssh2_packet_read() raw", + &p->buf[remainbuf], nread); + /* advance write pointer */ + p->writeidx += nread; + + /* update remainbuf counter */ + remainbuf = p->writeidx - p->readidx; + } + + /* how much data to deal with from the buffer */ + numbytes = remainbuf; + + if(!p->total_num) { + /* No payload package area allocated yet. To know the + size of this payload, we need to decrypt the first + blocksize data. */ + + if(encrypted) { + rc = decrypt(session, &p->buf[p->readidx], + block, blocksize); + if(rc != PACKET_NONE) { + return rc; } - else { - encrypted = 0; /* not encrypted */ - blocksize = 5; /* not strictly true, but we can use 5 - here to make the checks below work - fine still */ + /* save the first 5 bytes of the decrypted + package, to be used in the hash calculation + later down. */ + memcpy(p->init, &p->buf[p->readidx], 5); + } + else { + /* the data is plain, just copy it verbatim to + the working block buffer */ + memcpy(block, &p->buf[p->readidx], blocksize); + } + + /* advance the read pointer */ + p->readidx += blocksize; + + /* we now have the initial blocksize bytes decrypted, + and we can extract packet and padding length from it + */ + p->packet_length = libssh2_ntohu32(block); + p->padding_length = block[4]; + + /* total_num is the number of bytes following the + initial (5 bytes) packet length and padding length + fields */ + p->total_num = p->packet_length -1 + + (encrypted?session->remote.mac->mac_len:0); + + /* RFC4253 section 6.1 Maximum Packet Length says: + * + * "All implementations MUST be able to process + * packets with uncompressed payload length of 32768 + * bytes or less and total packet size of 35000 bytes + * or less (including length, padding length, payload, + * padding, and MAC.)." + */ + if(p->total_num > LIBSSH2_PACKET_MAXPAYLOAD) { + return PACKET_TOOBIG; + } + + /* Get a packet handle put data into. We get one to + hold all data, including padding and MAC. */ + p->payload = LIBSSH2_ALLOC(session, p->total_num); + if(!p->payload) { + return PACKET_ENOMEM; + } + /* init write pointer to start of payload buffer */ + p->wptr = p->payload; + + if(blocksize > 5) { + /* copy the data from index 5 to the end of + the blocksize from the temporary buffer to + the start of the decrypted buffer */ + memcpy(p->wptr, &block[5], blocksize-5); + p->wptr += blocksize-5; /* advance write + pointer */ + } + + /* init the data_num field to the number of bytes of + the package read so far */ + p->data_num = p->wptr - p->payload; + + /* we already dealt with a blocksize worth of data */ + numbytes -= blocksize; + } + + /* how much there is left to add to the current payload + package */ + remainpack = p->total_num - p->data_num; + + if(numbytes > remainpack) { + /* if we have more data in the buffer than what is + going into this particular packet, we limit this + round to this packet only */ + numbytes = remainpack; + } + + if(encrypted) { + /* At the end of the incoming stream, there is a MAC, + and we don't want to decrypt that since we need it + "raw". We MUST however decrypt the padding data + since it is used for the hash later on. */ + int skip = session->remote.mac->mac_len; + + /* if what we have plus numbytes is bigger than the + total minus the skip margin, we should lower the + amount to decrypt even more */ + if((p->data_num + numbytes) > (p->total_num - skip)) { + numdecrypt = (p->total_num - skip) - + p->data_num; + } + else { + int frac; + numdecrypt = numbytes; + frac = numdecrypt % blocksize; + if(frac) { + /* not an aligned amount of blocks, + align it */ + numdecrypt -= frac; + /* and make it no unencrypted data + after it */ + numbytes = 0; } - minimum = p->total_num ? p->total_num - p->data_num : blocksize; + } + } + else { + /* unencrypted data should not be decrypted at all */ + numdecrypt = 0; + } + + /* if there are bytes to decrypt, do that */ + if(numdecrypt > 0) { + /* now decrypt the lot */ + rc = decrypt(session, &p->buf[p->readidx], + p->wptr, numdecrypt); + if(rc != PACKET_NONE) { + return rc; + } + + /* advance the read pointer */ + p->readidx += numdecrypt; + /* advance write pointer */ + p->wptr += numdecrypt; + /* increse data_num */ + p->data_num += numdecrypt; + + /* bytes left to take care of without decryption */ + numbytes -= numdecrypt; + } + + /* if there are bytes to copy that aren't decrypted, simply + copy them as-is to the target buffer */ + if(numbytes > 0) { + memcpy(p->wptr, &p->buf[p->readidx], numbytes); + + /* advance the read pointer */ + p->readidx += numbytes; + /* advance write pointer */ + p->wptr += numbytes; + /* increse data_num */ + p->data_num += numbytes; + } + + /* now check how much data there's left to read to finish the + current packet */ + remainpack = p->total_num - p->data_num; + + if(!remainpack) { + /* we have a full packet */ + rc = fullpacket(session, encrypted); + + p->total_num = 0; /* no packet buffer available */ + + return rc; + } + } while (1); /* loop */ - /* read/use a whole big chunk into a temporary area stored in - the LIBSSH2_SESSION struct. We will decrypt data from that - buffer into the packet buffer so this temp one doesn't have - to be able to keep a whole SSH packet, just be large enough - so that we can read big chunks from the network layer. */ - - /* how much data there is remaining in the buffer to deal with - before we should read more from the network */ - remainbuf = p->writeidx - p->readidx; - - /* if remainbuf turns negative we have a bad internal error */ - assert(remainbuf >= 0); - - while(remainbuf < minimum) { - /* While there is too little data to deal with, read - more */ - ssize_t nread; - - /* move any remainder to the start of the buffer so - that we can do a full refill */ - if(remainbuf) { - memmove(p->buf, &p->buf[p->readidx], - remainbuf); - p->readidx = 0; - p->writeidx = remainbuf; - } - else { - /* nothing to move, just zero the indexes */ - p->readidx = p->writeidx = 0; - } - - /* now read a big chunk from the network into the temp - buffer */ - nread = recv(session->socket_fd, &p->buf[remainbuf], - PACKETBUFSIZE-remainbuf, - LIBSSH2_SOCKET_RECV_FLAGS(session)); - if (nread <= 0) { - /* check if this is due to EAGAIN and return - the special return code if so, error out - normally otherwise */ - if(errno == EAGAIN) { - return PACKET_EAGAIN; - } - return PACKET_FAIL; - } - debugdump(session, "libssh2_packet_read() raw", - &p->buf[remainbuf], nread); - /* advance write pointer */ - p->writeidx += nread; - - /* update remainbuf counter */ - remainbuf = p->writeidx - p->readidx; - } - - /* how much data to deal with from the buffer */ - numbytes = remainbuf; - - if(!p->total_num) { - /* No payload package area allocated yet. To know the - size of this payload, we need to decrypt the first - blocksize data. */ - - if(encrypted) { - rc = decrypt(session, &p->buf[p->readidx], - block, blocksize); - if(rc != PACKET_NONE) { - return rc; - } - /* save the first 5 bytes of the decrypted - package, to be used in the hash calculation - later down. */ - memcpy(p->init, &p->buf[p->readidx], 5); - } - else { - /* the data is plain, just copy it verbatim to - the working block buffer */ - memcpy(block, &p->buf[p->readidx], blocksize); - } - - /* advance the read pointer */ - p->readidx += blocksize; - - /* we now have the initial blocksize bytes decrypted, - and we can extract packet and padding length from it - */ - p->packet_length = libssh2_ntohu32(block); - p->padding_length = block[4]; - - /* total_num is the number of bytes following the - initial (5 bytes) packet length and padding length - fields */ - p->total_num = p->packet_length -1 + - (encrypted?session->remote.mac->mac_len:0); - - /* RFC4253 section 6.1 Maximum Packet Length says: - * - * "All implementations MUST be able to process - * packets with uncompressed payload length of 32768 - * bytes or less and total packet size of 35000 bytes - * or less (including length, padding length, payload, - * padding, and MAC.)." - */ - if(p->total_num > LIBSSH2_PACKET_MAXPAYLOAD) { - return PACKET_TOOBIG; - } - - /* Get a packet handle put data into. We get one to - hold all data, including padding and MAC. */ - p->payload = LIBSSH2_ALLOC(session, p->total_num); - if(!p->payload) { - return PACKET_ENOMEM; - } - /* init write pointer to start of payload buffer */ - p->wptr = p->payload; - - if(blocksize > 5) { - /* copy the data from index 5 to the end of - the blocksize from the temporary buffer to - the start of the decrypted buffer */ - memcpy(p->wptr, &block[5], blocksize-5); - p->wptr += blocksize-5; /* advance write - pointer */ - } - - /* init the data_num field to the number of bytes of - the package read so far */ - p->data_num = p->wptr - p->payload; - - /* we already dealt with a blocksize worth of data */ - numbytes -= blocksize; - } - - /* how much there is left to add to the current payload - package */ - remainpack = p->total_num - p->data_num; - - if(numbytes > remainpack) { - /* if we have more data in the buffer than what is - going into this particular packet, we limit this - round to this packet only */ - numbytes = remainpack; - } - - if(encrypted) { - /* At the end of the incoming stream, there is a MAC, - and we don't want to decrypt that since we need it - "raw". We MUST however decrypt the padding data - since it is used for the hash later on. */ - int skip = session->remote.mac->mac_len; - - /* if what we have plus numbytes is bigger than the - total minus the skip margin, we should lower the - amount to decrypt even more */ - if((p->data_num + numbytes) > (p->total_num - skip)) { - numdecrypt = (p->total_num - skip) - - p->data_num; - } - else { - int frac; - numdecrypt = numbytes; - frac = numdecrypt % blocksize; - if(frac) { - /* not an aligned amount of blocks, - align it */ - numdecrypt -= frac; - /* and make it no unencrypted data - after it */ - numbytes = 0; - } - } - } - else { - /* unencrypted data should not be decrypted at all */ - numdecrypt = 0; - } - - /* if there are bytes to decrypt, do that */ - if(numdecrypt > 0) { - /* now decrypt the lot */ - rc = decrypt(session, &p->buf[p->readidx], - p->wptr, numdecrypt); - if(rc != PACKET_NONE) { - return rc; - } - - /* advance the read pointer */ - p->readidx += numdecrypt; - /* advance write pointer */ - p->wptr += numdecrypt; - /* increse data_num */ - p->data_num += numdecrypt; - - /* bytes left to take care of without decryption */ - numbytes -= numdecrypt; - } - - /* if there are bytes to copy that aren't decrypted, simply - copy them as-is to the target buffer */ - if(numbytes > 0) { - memcpy(p->wptr, &p->buf[p->readidx], numbytes); - - /* advance the read pointer */ - p->readidx += numbytes; - /* advance write pointer */ - p->wptr += numbytes; - /* increse data_num */ - p->data_num += numbytes; - } - - /* now check how much data there's left to read to finish the - current packet */ - remainpack = p->total_num - p->data_num; - - if(!remainpack) { - /* we have a full packet */ - rc = fullpacket(session, encrypted); - - p->total_num = 0; /* no packet buffer available */ - - return rc; - } - } while (1); /* loop */ - - return PACKET_FAIL; /* we never reach this point */ + return PACKET_FAIL; /* we never reach this point */ } /* }}} */ @@ -506,54 +506,54 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned long data_len, ssize_t *ret) { - ssize_t rc; - ssize_t length; - struct transportpacket *p = &session->packet; - - if(!p->outbuf) { - *ret = 0; - return PACKET_NONE; - } - - /* send as much as possible of the existing packet */ - if((data != p->odata) || (data_len != p->olen)) { - /* When we are about to complete the sending of a packet, it - is vital that the caller doesn't try to send a - new/different packet since we don't add this one up until - the previous one has been sent. To make the caller really - notice his/hers flaw, we return error for this case */ - return PACKET_BADUSE; - } - - *ret = 1; /* set to make our parent return */ - - /* number of bytes left to send */ - length = p->ototal_num - p->osent; - - rc = send(session->socket_fd, - &p->outbuf[p->osent], - length, LIBSSH2_SOCKET_SEND_FLAGS(session)); - - if(rc == length) { - /* the remainder of the package was sent */ - LIBSSH2_FREE(session, p->outbuf); - p->outbuf = NULL; - p->ototal_num = 0; - } - else if(rc < 0) { - /* nothing was sent */ - if(errno != EAGAIN) { - /* send failure! */ - return PACKET_FAIL; - } - return PACKET_EAGAIN; - } - - debugdump(session, "libssh2_packet_write send()", - &p->outbuf[p->osent], length); - p->osent += length; /* we sent away this much data */ - + ssize_t rc; + ssize_t length; + struct transportpacket *p = &session->packet; + + if(!p->outbuf) { + *ret = 0; return PACKET_NONE; + } + + /* send as much as possible of the existing packet */ + if((data != p->odata) || (data_len != p->olen)) { + /* When we are about to complete the sending of a packet, it + is vital that the caller doesn't try to send a + new/different packet since we don't add this one up until + the previous one has been sent. To make the caller really + notice his/hers flaw, we return error for this case */ + return PACKET_BADUSE; + } + + *ret = 1; /* set to make our parent return */ + + /* number of bytes left to send */ + length = p->ototal_num - p->osent; + + rc = send(session->socket_fd, + &p->outbuf[p->osent], + length, LIBSSH2_SOCKET_SEND_FLAGS(session)); + + if(rc == length) { + /* the remainder of the package was sent */ + LIBSSH2_FREE(session, p->outbuf); + p->outbuf = NULL; + p->ototal_num = 0; + } + else if(rc < 0) { + /* nothing was sent */ + if(errno != EAGAIN) { + /* send failure! */ + return PACKET_FAIL; + } + return PACKET_EAGAIN; + } + + debugdump(session, "libssh2_packet_write send()", + &p->outbuf[p->osent], length); + p->osent += length; /* we sent away this much data */ + + return PACKET_NONE; } /* {{{ libssh2_packet_write @@ -568,157 +568,157 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len) { - int blocksize = - (session->state & LIBSSH2_STATE_NEWKEYS) ? - session->local.crypt->blocksize : 8; - int padding_length; - int packet_length; - int total_length; - int free_data=0; + int blocksize = + (session->state & LIBSSH2_STATE_NEWKEYS) ? + session->local.crypt->blocksize : 8; + int padding_length; + int packet_length; + int total_length; + int free_data=0; #ifdef RANDOM_PADDING - int rand_max; - int seed = data[0]; /* FIXME: make this random */ + int rand_max; + int seed = data[0]; /* FIXME: make this random */ #endif - struct transportpacket *p = &session->packet; - int encrypted; - int i; - ssize_t ret; - libssh2pack_t rc; - unsigned char *orgdata = data; - unsigned long orgdata_len = data_len; - - debugdump(session, "libssh2_packet_write plain", data, data_len); - - /* FIRST, check if we have a pending write to complete */ - rc = send_existing(session, data, data_len, &ret); - if(rc || ret) - return rc; - - encrypted = (session->state & LIBSSH2_STATE_NEWKEYS)?1:0; - - /* check if we should compress */ - if (encrypted && strcmp(session->local.comp->name, "none")) { - if (session->local.comp->comp(session, 1, &data, &data_len, - LIBSSH2_PACKET_MAXCOMP, - &free_data, data, data_len, - &session->local.comp_abstract)) { - return PACKET_COMPRESS; /* compression failure */ - } - } - - /* RFC4253 says: Note that the length of the concatenation of - 'packet_length', 'padding_length', 'payload', and 'random padding' - MUST be a multiple of the cipher block size or 8, whichever is - larger. */ - - /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == - 0 */ - - packet_length = data_len + 1 + 4; /* 1 is for padding_length field - 4 for the packet_length field */ - - /* at this point we have it all except the padding */ - - /* first figure out our minimum padding amount to make it an even - block size */ - padding_length = blocksize - (packet_length % blocksize); - - /* if the padding becomes too small we add another blocksize worth - of it (taken from the original libssh2 where it didn't have any - real explanation) */ - if (padding_length < 4) { - padding_length += blocksize; + struct transportpacket *p = &session->packet; + int encrypted; + int i; + ssize_t ret; + libssh2pack_t rc; + unsigned char *orgdata = data; + unsigned long orgdata_len = data_len; + + debugdump(session, "libssh2_packet_write plain", data, data_len); + + /* FIRST, check if we have a pending write to complete */ + rc = send_existing(session, data, data_len, &ret); + if(rc || ret) + return rc; + + encrypted = (session->state & LIBSSH2_STATE_NEWKEYS)?1:0; + + /* check if we should compress */ + if (encrypted && strcmp(session->local.comp->name, "none")) { + if (session->local.comp->comp(session, 1, &data, &data_len, + LIBSSH2_PACKET_MAXCOMP, + &free_data, data, data_len, + &session->local.comp_abstract)) { + return PACKET_COMPRESS; /* compression failure */ } + } + + /* RFC4253 says: Note that the length of the concatenation of + 'packet_length', 'padding_length', 'payload', and 'random padding' + MUST be a multiple of the cipher block size or 8, whichever is + larger. */ + + /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == + 0 */ + + packet_length = data_len + 1 + 4; /* 1 is for padding_length field + 4 for the packet_length field */ + + /* at this point we have it all except the padding */ + + /* first figure out our minimum padding amount to make it an even + block size */ + padding_length = blocksize - (packet_length % blocksize); + + /* if the padding becomes too small we add another blocksize worth + of it (taken from the original libssh2 where it didn't have any + real explanation) */ + if (padding_length < 4) { + padding_length += blocksize; + } #ifdef RANDOM_PADDING - /* FIXME: we can add padding here, but that also makes the packets - bigger etc */ - - /* now we can add 'blocksize' to the padding_length N number of times - (to "help thwart traffic analysis") but it must be less than 255 in - total */ - rand_max = (255 - padding_length)/blocksize + 1; - padding_length += blocksize * (seed % rand_max); + /* FIXME: we can add padding here, but that also makes the packets + bigger etc */ + + /* now we can add 'blocksize' to the padding_length N number of times + (to "help thwart traffic analysis") but it must be less than 255 in + total */ + rand_max = (255 - padding_length)/blocksize + 1; + padding_length += blocksize * (seed % rand_max); #endif - - packet_length += padding_length; - - /* append the MAC length to the total_length size */ - total_length = packet_length + - (encrypted?session->local.mac->mac_len:0); - - /* allocate memory to store the outgoing packet in, in case we can't - send the whole one and thus need to keep it after this function - returns. */ - p->outbuf = LIBSSH2_ALLOC(session, total_length); - if(!p->outbuf) { - return PACKET_ENOMEM; + + packet_length += padding_length; + + /* append the MAC length to the total_length size */ + total_length = packet_length + + (encrypted?session->local.mac->mac_len:0); + + /* allocate memory to store the outgoing packet in, in case we can't + send the whole one and thus need to keep it after this function + returns. */ + p->outbuf = LIBSSH2_ALLOC(session, total_length); + if(!p->outbuf) { + return PACKET_ENOMEM; + } + + /* store packet_length, which is the size of the whole packet except + the MAC and the packet_length field itself */ + libssh2_htonu32(p->outbuf, packet_length - 4); + /* store padding_length */ + p->outbuf[4] = padding_length; + /* copy the payload data */ + memcpy(p->outbuf + 5, data, data_len); + /* fill the padding area with random junk */ + libssh2_random(p->outbuf + 5 + data_len, padding_length); + if (free_data) { + LIBSSH2_FREE(session, data); + } + + if(encrypted) { + /* Calculate MAC hash. Put the output at index packet_length, + since that size includes the whole packet. The MAC is + calculated on the entire unencrypted packet, including all + fields except the MAC field itself. */ + session->local.mac->hash(session, + p->outbuf + packet_length, + session->local.seqno, + p->outbuf, packet_length, + NULL, 0, + &session->local.mac_abstract); + + /* Encrypt the whole packet data, one block size at a time. + The MAC field is not encrypted. */ + for(i=0; i < packet_length; + i += session->local.crypt->blocksize) { + unsigned char *ptr = &p->outbuf[i]; + if(session->local.crypt->crypt(session, ptr, + &session->local.crypt_abstract)) + return PACKET_FAIL; /* encryption failure */ } - - /* store packet_length, which is the size of the whole packet except - the MAC and the packet_length field itself */ - libssh2_htonu32(p->outbuf, packet_length - 4); - /* store padding_length */ - p->outbuf[4] = padding_length; - /* copy the payload data */ - memcpy(p->outbuf + 5, data, data_len); - /* fill the padding area with random junk */ - libssh2_random(p->outbuf + 5 + data_len, padding_length); - if (free_data) { - LIBSSH2_FREE(session, data); + } + + session->local.seqno++; + + ret = send(session->socket_fd, p->outbuf, + total_length, LIBSSH2_SOCKET_SEND_FLAGS(session)); + + if(ret != -1) { + debugdump(session, "libssh2_packet_write send()", + p->outbuf, ret); + } + if(ret != total_length) { + if((ret > 0 ) || + ((ret == -1) && (errno == EAGAIN))) { + /* the whole packet could not be sent, save the rest */ + p->odata = orgdata; + p->olen = orgdata_len; + p->osent = (ret == -1)?0:ret; + p->ototal_num = total_length; + return PACKET_EAGAIN; } - - if(encrypted) { - /* Calculate MAC hash. Put the output at index packet_length, - since that size includes the whole packet. The MAC is - calculated on the entire unencrypted packet, including all - fields except the MAC field itself. */ - session->local.mac->hash(session, - p->outbuf + packet_length, - session->local.seqno, - p->outbuf, packet_length, - NULL, 0, - &session->local.mac_abstract); - - /* Encrypt the whole packet data, one block size at a time. - The MAC field is not encrypted. */ - for(i=0; i < packet_length; - i += session->local.crypt->blocksize) { - unsigned char *ptr = &p->outbuf[i]; - if(session->local.crypt->crypt(session, ptr, - &session->local.crypt_abstract)) - return PACKET_FAIL; /* encryption failure */ - } - } - - session->local.seqno++; - - ret = send(session->socket_fd, p->outbuf, - total_length, LIBSSH2_SOCKET_SEND_FLAGS(session)); - - if(ret != -1) { - debugdump(session, "libssh2_packet_write send()", - p->outbuf, ret); - } - if(ret != total_length) { - if((ret > 0 ) || - ((ret == -1) && (errno == EAGAIN))) { - /* the whole packet could not be sent, save the rest */ - p->odata = orgdata; - p->olen = orgdata_len; - p->osent = (ret == -1)?0:ret; - p->ototal_num = total_length; - return PACKET_EAGAIN; - } - return PACKET_FAIL; - } - - /* the whole thing got sent away */ - p->odata = NULL; - p->olen = 0; - LIBSSH2_FREE(session, p->outbuf); - p->outbuf = NULL; - - return PACKET_NONE; /* all is good */ + return PACKET_FAIL; + } + + /* the whole thing got sent away */ + p->odata = NULL; + p->olen = 0; + LIBSSH2_FREE(session, p->outbuf); + p->outbuf = NULL; + + return PACKET_NONE; /* all is good */ } /* }}} */ diff --git a/src/userauth.c b/src/userauth.c index b7f61ad..912f226 100644 --- a/src/userauth.c +++ b/src/userauth.c @@ -54,53 +54,53 @@ */ LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len) { - static const unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; - unsigned long data_len = username_len + 31; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" + - method_len(4) + method(4)"none" */ - unsigned long methods_len; - unsigned char *data, *s; + static const unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; + unsigned long data_len = username_len + 31; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" + + method_len(4) + method(4)"none" */ + unsigned long methods_len; + unsigned char *data, *s; - s = data = LIBSSH2_ALLOC(session, data_len); - if (!data) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth_list", 0); - return NULL; - } + s = data = LIBSSH2_ALLOC(session, data_len); + if (!data) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth_list", 0); + return NULL; + } - *(s++) = SSH_MSG_USERAUTH_REQUEST; - libssh2_htonu32(s, username_len); s += 4; - if (username) { - memcpy(s, username, username_len); s += username_len; - } + *(s++) = SSH_MSG_USERAUTH_REQUEST; + libssh2_htonu32(s, username_len); s += 4; + if (username) { + memcpy(s, username, username_len); s += username_len; + } - libssh2_htonu32(s, 14); s += 4; - memcpy(s, "ssh-connection", 14); s += 14; + libssh2_htonu32(s, 14); s += 4; + memcpy(s, "ssh-connection", 14); s += 14; - libssh2_htonu32(s, 4); s += 4; - memcpy(s, "none", 4); s += 4; + libssh2_htonu32(s, 4); s += 4; + memcpy(s, "none", 4); s += 4; - if (libssh2_packet_write(session, data, data_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-none request", 0); - LIBSSH2_FREE(session, data); - return NULL; - } - LIBSSH2_FREE(session, data); + if (libssh2_packet_write(session, data, data_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-none request", 0); + LIBSSH2_FREE(session, data); + return NULL; + } + LIBSSH2_FREE(session, data); - if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { - return NULL; - } + if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { + return NULL; + } - if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { - /* Wow, who'dve thought... */ - LIBSSH2_FREE(session, data); - session->state |= LIBSSH2_STATE_AUTHENTICATED; - return NULL; - } + if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { + /* Wow, who'dve thought... */ + LIBSSH2_FREE(session, data); + session->state |= LIBSSH2_STATE_AUTHENTICATED; + return NULL; + } - methods_len = libssh2_ntohu32(data + 1); - memcpy(data, data + 5, methods_len); - data[methods_len] = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s", data); - return (char *)data; + methods_len = libssh2_ntohu32(data + 1); + memcpy(data, data + 5, methods_len); + data[methods_len] = '\0'; + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s", data); + return (char *)data; } /* }}} */ @@ -110,7 +110,7 @@ LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *us */ LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session) { - return session->state & LIBSSH2_STATE_AUTHENTICATED; + return session->state & LIBSSH2_STATE_AUTHENTICATED; } /* }}} */ @@ -118,113 +118,113 @@ LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session) * Plain ol' login */ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, - const char *password, unsigned int password_len, - LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))) + const char *password, unsigned int password_len, + LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))) { - unsigned char *data, *s; - static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 }; - unsigned long data_len = username_len + password_len + 40; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" + - method_len(4) + method(8)"password" + chgpwdbool(1) + password_len(4) */ + unsigned char *data, *s; + static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 }; + unsigned long data_len = username_len + password_len + 40; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" + + method_len(4) + method(8)"password" + chgpwdbool(1) + password_len(4) */ - s = data = LIBSSH2_ALLOC(session, data_len); - if (!data) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth-password request", 0); - return -1; - } + s = data = LIBSSH2_ALLOC(session, data_len); + if (!data) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth-password request", 0); + return -1; + } - *(s++) = SSH_MSG_USERAUTH_REQUEST; - libssh2_htonu32(s, username_len); s += 4; - memcpy(s, username, username_len); s += username_len; + *(s++) = SSH_MSG_USERAUTH_REQUEST; + libssh2_htonu32(s, username_len); s += 4; + memcpy(s, username, username_len); s += username_len; - libssh2_htonu32(s, sizeof("ssh-connection") - 1); s += 4; - memcpy(s, "ssh-connection", sizeof("ssh-connection") - 1); s += sizeof("ssh-connection") - 1; + libssh2_htonu32(s, sizeof("ssh-connection") - 1); s += 4; + memcpy(s, "ssh-connection", sizeof("ssh-connection") - 1); s += sizeof("ssh-connection") - 1; - libssh2_htonu32(s, sizeof("password") - 1); s += 4; - memcpy(s, "password", sizeof("password") - 1); s += sizeof("password") - 1; + libssh2_htonu32(s, sizeof("password") - 1); s += 4; + memcpy(s, "password", sizeof("password") - 1); s += sizeof("password") - 1; - *s = '\0'; s++; + *s = '\0'; s++; - libssh2_htonu32(s, password_len); s += 4; - memcpy(s, password, password_len); s += password_len; + libssh2_htonu32(s, password_len); s += 4; + memcpy(s, password, password_len); s += password_len; - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting to login using password authentication"); - if (libssh2_packet_write(session, data, data_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password request", 0); - LIBSSH2_FREE(session, data); - return -1; - } - LIBSSH2_FREE(session, data); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting to login using password authentication"); + if (libssh2_packet_write(session, data, data_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password request", 0); + LIBSSH2_FREE(session, data); + return -1; + } + LIBSSH2_FREE(session, data); password_response: - if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { - return -1; - } + if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { + return -1; + } - if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password authentication successful"); - LIBSSH2_FREE(session, data); - session->state |= LIBSSH2_STATE_AUTHENTICATED; - return 0; - } + if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password authentication successful"); + LIBSSH2_FREE(session, data); + session->state |= LIBSSH2_STATE_AUTHENTICATED; + return 0; + } - if (data[0] == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) { - char *newpw = NULL; - int newpw_len = 0; + if (data[0] == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) { + char *newpw = NULL; + int newpw_len = 0; - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password change required"); - LIBSSH2_FREE(session, data); - if (passwd_change_cb) { - passwd_change_cb(session, &newpw, &newpw_len, &session->abstract); - if (!newpw) { - libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password expired, and callback failed", 0); - return -1; - } - data_len = username_len + password_len + 44 + newpw_len; /* basic data_len + newpw_len(4) */ - s = data = LIBSSH2_ALLOC(session, data_len); - if (!data) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth-password-change request", 0); - LIBSSH2_FREE(session, newpw); - return -1; - } + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password change required"); + LIBSSH2_FREE(session, data); + if (passwd_change_cb) { + passwd_change_cb(session, &newpw, &newpw_len, &session->abstract); + if (!newpw) { + libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password expired, and callback failed", 0); + return -1; + } + data_len = username_len + password_len + 44 + newpw_len; /* basic data_len + newpw_len(4) */ + s = data = LIBSSH2_ALLOC(session, data_len); + if (!data) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth-password-change request", 0); + LIBSSH2_FREE(session, newpw); + return -1; + } - *(s++) = SSH_MSG_USERAUTH_REQUEST; - libssh2_htonu32(s, username_len); s += 4; - memcpy(s, username, username_len); s += username_len; + *(s++) = SSH_MSG_USERAUTH_REQUEST; + libssh2_htonu32(s, username_len); s += 4; + memcpy(s, username, username_len); s += username_len; - libssh2_htonu32(s, sizeof("ssh-connection") - 1); s += 4; - memcpy(s, "ssh-connection", sizeof("ssh-connection") - 1); s += sizeof("ssh-connection") - 1; + libssh2_htonu32(s, sizeof("ssh-connection") - 1); s += 4; + memcpy(s, "ssh-connection", sizeof("ssh-connection") - 1); s += sizeof("ssh-connection") - 1; - libssh2_htonu32(s, sizeof("password") - 1); s += 4; - memcpy(s, "password", sizeof("password") - 1); s += sizeof("password") - 1; + libssh2_htonu32(s, sizeof("password") - 1); s += 4; + memcpy(s, "password", sizeof("password") - 1); s += sizeof("password") - 1; - *s = 0xFF; s++; + *s = 0xFF; s++; - libssh2_htonu32(s, password_len); s += 4; - memcpy(s, password, password_len); s += password_len; + libssh2_htonu32(s, password_len); s += 4; + memcpy(s, password, password_len); s += password_len; - libssh2_htonu32(s, newpw_len); s += 4; - memcpy(s, newpw, newpw_len); s += newpw_len; + libssh2_htonu32(s, newpw_len); s += 4; + memcpy(s, newpw, newpw_len); s += newpw_len; - if (libssh2_packet_write(session, data, data_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password-change request", 0); - LIBSSH2_FREE(session, data); - LIBSSH2_FREE(session, newpw); - return -1; - } - LIBSSH2_FREE(session, data); - LIBSSH2_FREE(session, newpw); + if (libssh2_packet_write(session, data, data_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password-change request", 0); + LIBSSH2_FREE(session, data); + LIBSSH2_FREE(session, newpw); + return -1; + } + LIBSSH2_FREE(session, data); + LIBSSH2_FREE(session, newpw); - /* Ugliest use of goto ever. Blame it on the askN => requirev migration. */ - goto password_response; - } else { - libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password Expired, and no callback specified", 0); - return -1; - } - } + /* Ugliest use of goto ever. Blame it on the askN => requirev migration. */ + goto password_response; + } else { + libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password Expired, and no callback specified", 0); + return -1; + } + } - /* FAILURE */ - LIBSSH2_FREE(session, data); - return -1; + /* FAILURE */ + LIBSSH2_FREE(session, data); + return -1; } /* }}} */ @@ -232,120 +232,120 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const cha * Read a public key from an id_???.pub style file */ static int libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char **method, unsigned long *method_len, - unsigned char **pubkeydata, unsigned long *pubkeydata_len, - const char *pubkeyfile) + unsigned char **pubkeydata, unsigned long *pubkeydata_len, + const char *pubkeyfile) { - FILE *fd; - char c; - unsigned char *pubkey = NULL, *sp1, *sp2, *tmp; - size_t pubkey_len = 0; - unsigned int tmp_len; + FILE *fd; + char c; + unsigned char *pubkey = NULL, *sp1, *sp2, *tmp; + size_t pubkey_len = 0; + unsigned int tmp_len; - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading public key file: %s", pubkeyfile); - /* Read Public Key */ - fd = fopen(pubkeyfile, "r"); - if (!fd) { - libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to open public key file", 0); - return -1; - } - while (!feof(fd) && (c = fgetc(fd)) != '\r' && c != '\n') pubkey_len++; - if (feof(fd)) { - /* the last character was EOF */ - pubkey_len--; - } - rewind(fd); - - if (pubkey_len <= 1) { - libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid data in public key file", 0); - fclose(fd); - return -1; - } + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading public key file: %s", pubkeyfile); + /* Read Public Key */ + fd = fopen(pubkeyfile, "r"); + if (!fd) { + libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to open public key file", 0); + return -1; + } + while (!feof(fd) && (c = fgetc(fd)) != '\r' && c != '\n') pubkey_len++; + if (feof(fd)) { + /* the last character was EOF */ + pubkey_len--; + } + rewind(fd); + + if (pubkey_len <= 1) { + libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid data in public key file", 0); + fclose(fd); + return -1; + } - pubkey = LIBSSH2_ALLOC(session, pubkey_len); - if (!pubkey) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for public key data", 0); - fclose(fd); - return -1; - } - if (fread(pubkey, 1, pubkey_len, fd) != pubkey_len) { - libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to read public key from file", 0); - LIBSSH2_FREE(session, pubkey); - fclose(fd); - return -1; - } - fclose(fd); - /* - * Remove trailing whitespace - */ - while (pubkey_len && isspace(pubkey[pubkey_len-1])) pubkey_len--; + pubkey = LIBSSH2_ALLOC(session, pubkey_len); + if (!pubkey) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for public key data", 0); + fclose(fd); + return -1; + } + if (fread(pubkey, 1, pubkey_len, fd) != pubkey_len) { + libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to read public key from file", 0); + LIBSSH2_FREE(session, pubkey); + fclose(fd); + return -1; + } + fclose(fd); + /* + * Remove trailing whitespace + */ + while (pubkey_len && isspace(pubkey[pubkey_len-1])) pubkey_len--; - if (!pubkey_len) { - libssh2_error(session, LIBSSH2_ERROR_FILE, "Missing public key data", 0); - LIBSSH2_FREE(session, pubkey); - return -1; - } + if (!pubkey_len) { + libssh2_error(session, LIBSSH2_ERROR_FILE, "Missing public key data", 0); + LIBSSH2_FREE(session, pubkey); + return -1; + } - if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) { - libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid public key data", 0); - LIBSSH2_FREE(session, pubkey); - return -1; - } - /* Wasting some bytes here (okay, more than some), - * but since it's likely to be freed soon anyway, - * we'll just avoid the extra free/alloc and call it a wash */ - *method = pubkey; - *method_len = sp1 - pubkey; + if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) { + libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid public key data", 0); + LIBSSH2_FREE(session, pubkey); + return -1; + } + /* Wasting some bytes here (okay, more than some), + * but since it's likely to be freed soon anyway, + * we'll just avoid the extra free/alloc and call it a wash */ + *method = pubkey; + *method_len = sp1 - pubkey; - sp1++; + sp1++; - if ((sp2 = memchr(sp1, ' ', pubkey_len - *method_len)) == NULL) { - /* Assume that the id string is missing, but that it's okay */ - sp2 = pubkey + pubkey_len; - } + if ((sp2 = memchr(sp1, ' ', pubkey_len - *method_len)) == NULL) { + /* Assume that the id string is missing, but that it's okay */ + sp2 = pubkey + pubkey_len; + } - if (libssh2_base64_decode(session, (char **)&tmp, &tmp_len, (char *)sp1, sp2 - sp1)) { - libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid key data, not base64 encoded", 0); - LIBSSH2_FREE(session, pubkey); - return -1; - } - *pubkeydata = tmp; - *pubkeydata_len = tmp_len; + if (libssh2_base64_decode(session, (char **)&tmp, &tmp_len, (char *)sp1, sp2 - sp1)) { + libssh2_error(session, LIBSSH2_ERROR_FILE, "Invalid key data, not base64 encoded", 0); + LIBSSH2_FREE(session, pubkey); + return -1; + } + *pubkeydata = tmp; + *pubkeydata_len = tmp_len; - return 0; + return 0; } /* }}} */ /* {{{ libssh2_file_read_privatekey * Read a PEM encoded private key from an id_??? style file */ -static int libssh2_file_read_privatekey(LIBSSH2_SESSION *session, const LIBSSH2_HOSTKEY_METHOD **hostkey_method, void **hostkey_abstract, - const unsigned char *method, int method_len, - const char *privkeyfile, const char *passphrase) +static int libssh2_file_read_privatekey(LIBSSH2_SESSION *session, const LIBSSH2_HOSTKEY_METHOD **hostkey_method, void **hostkey_abstract, + const unsigned char *method, int method_len, + const char *privkeyfile, const char *passphrase) { - const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = libssh2_hostkey_methods(); + const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = libssh2_hostkey_methods(); - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading private key file: %s", privkeyfile); - *hostkey_method = NULL; - *hostkey_abstract = NULL; - while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) { - if ((*hostkey_methods_avail)->initPEM && - strncmp((*hostkey_methods_avail)->name, (const char *)method, method_len) == 0) { - *hostkey_method = *hostkey_methods_avail; - break; - } - hostkey_methods_avail++; - } - if (!*hostkey_method) { - libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No handler for specified private key", 0); - return -1; - } + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading private key file: %s", privkeyfile); + *hostkey_method = NULL; + *hostkey_abstract = NULL; + while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) { + if ((*hostkey_methods_avail)->initPEM && + strncmp((*hostkey_methods_avail)->name, (const char *)method, method_len) == 0) { + *hostkey_method = *hostkey_methods_avail; + break; + } + hostkey_methods_avail++; + } + if (!*hostkey_method) { + libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, "No handler for specified private key", 0); + return -1; + } - if ((*hostkey_method)->initPEM(session, privkeyfile, passphrase, hostkey_abstract)) { - libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to initialize private key from file", 0); - return -1; - } + if ((*hostkey_method)->initPEM(session, privkeyfile, passphrase, hostkey_abstract)) { + libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to initialize private key from file", 0); + return -1; + } - return 0; + return 0; } /* }}} */ @@ -355,134 +355,134 @@ static int libssh2_file_read_privatekey(LIBSSH2_SESSION *session, const LIBSSH2_ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, const char *publickey, const char *privatekey, const char *passphrase, - const char *hostname, unsigned int hostname_len, - const char *local_username, unsigned int local_username_len) + const char *hostname, unsigned int hostname_len, + const char *local_username, unsigned int local_username_len) { - const LIBSSH2_HOSTKEY_METHOD *privkeyobj; - void *abstract; - unsigned char buf[5]; - struct iovec datavec[4]; - unsigned char *method, *pubkeydata, *packet, *s, *sig, *data; - static const unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; - unsigned long method_len, pubkeydata_len, packet_len, sig_len, data_len; + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + void *abstract; + unsigned char buf[5]; + struct iovec datavec[4]; + unsigned char *method, *pubkeydata, *packet, *s, *sig, *data; + static const unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; + unsigned long method_len, pubkeydata_len, packet_len, sig_len, data_len; - if (libssh2_file_read_publickey(session, &method, &method_len, &pubkeydata, &pubkeydata_len, publickey)) { - return -1; - } + if (libssh2_file_read_publickey(session, &method, &method_len, &pubkeydata, &pubkeydata_len, publickey)) { + return -1; + } - packet_len = username_len + method_len + hostname_len + local_username_len + pubkeydata_len + 48; - /* packet_type(1) + username_len(4) + servicename_len(4) + service_name(14)"ssh-connection" + - * authmethod_len(4) + authmethod(9)"hostbased" + method_len(4) + pubkeydata_len(4) + - * local_username_len(4) - */ - /* Preallocate space for an overall length, method name again, - * and the signature, which won't be any larger than the size of the publickeydata itself */ - s = packet = LIBSSH2_ALLOC(session, packet_len + 4 + (4 + method_len) + (4 + pubkeydata_len)); - if (!packet) { - LIBSSH2_FREE(session, method); - return -1; - } + packet_len = username_len + method_len + hostname_len + local_username_len + pubkeydata_len + 48; + /* packet_type(1) + username_len(4) + servicename_len(4) + service_name(14)"ssh-connection" + + * authmethod_len(4) + authmethod(9)"hostbased" + method_len(4) + pubkeydata_len(4) + + * local_username_len(4) + */ + /* Preallocate space for an overall length, method name again, + * and the signature, which won't be any larger than the size of the publickeydata itself */ + s = packet = LIBSSH2_ALLOC(session, packet_len + 4 + (4 + method_len) + (4 + pubkeydata_len)); + if (!packet) { + LIBSSH2_FREE(session, method); + return -1; + } - *(s++) = SSH_MSG_USERAUTH_REQUEST; - libssh2_htonu32(s, username_len); s += 4; - memcpy(s, username, username_len); s += username_len; + *(s++) = SSH_MSG_USERAUTH_REQUEST; + libssh2_htonu32(s, username_len); s += 4; + memcpy(s, username, username_len); s += username_len; - libssh2_htonu32(s, 14); s += 4; - memcpy(s, "ssh-connection", 14); s += 14; + libssh2_htonu32(s, 14); s += 4; + memcpy(s, "ssh-connection", 14); s += 14; - libssh2_htonu32(s, 9); s += 4; - memcpy(s, "hostbased", 9); s += 9; + libssh2_htonu32(s, 9); s += 4; + memcpy(s, "hostbased", 9); s += 9; - libssh2_htonu32(s, method_len); s += 4; - memcpy(s, method, method_len); s += method_len; + libssh2_htonu32(s, method_len); s += 4; + memcpy(s, method, method_len); s += method_len; - libssh2_htonu32(s, pubkeydata_len); s += 4; - memcpy(s, pubkeydata, pubkeydata_len); s += pubkeydata_len; + libssh2_htonu32(s, pubkeydata_len); s += 4; + memcpy(s, pubkeydata, pubkeydata_len); s += pubkeydata_len; - libssh2_htonu32(s, hostname_len); s += 4; - memcpy(s, hostname, hostname_len); s += hostname_len; + libssh2_htonu32(s, hostname_len); s += 4; + memcpy(s, hostname, hostname_len); s += hostname_len; - libssh2_htonu32(s, local_username_len); s += 4; - memcpy(s, local_username, local_username_len); s += local_username_len; + libssh2_htonu32(s, local_username_len); s += 4; + memcpy(s, local_username, local_username_len); s += local_username_len; - if (libssh2_file_read_privatekey(session, &privkeyobj, &abstract, method, method_len, privatekey, passphrase)) { - LIBSSH2_FREE(session, method); - LIBSSH2_FREE(session, packet); - return -1; - } + if (libssh2_file_read_privatekey(session, &privkeyobj, &abstract, method, method_len, privatekey, passphrase)) { + LIBSSH2_FREE(session, method); + LIBSSH2_FREE(session, packet); + return -1; + } - libssh2_htonu32(buf, session->session_id_len); - datavec[0].iov_base = buf; - datavec[0].iov_len = 4; - datavec[1].iov_base = session->session_id; - datavec[1].iov_len = session->session_id_len; - datavec[2].iov_base = packet; - datavec[2].iov_len = packet_len; + libssh2_htonu32(buf, session->session_id_len); + datavec[0].iov_base = buf; + datavec[0].iov_len = 4; + datavec[1].iov_base = session->session_id; + datavec[1].iov_len = session->session_id_len; + datavec[2].iov_base = packet; + datavec[2].iov_len = packet_len; - if (privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) { - LIBSSH2_FREE(session, method); - LIBSSH2_FREE(session, packet); - if (privkeyobj->dtor) { - privkeyobj->dtor(session, &abstract); - } - return -1; - } + if (privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) { + LIBSSH2_FREE(session, method); + LIBSSH2_FREE(session, packet); + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &abstract); + } + return -1; + } - if (privkeyobj->dtor) { - privkeyobj->dtor(session, &abstract); - } + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &abstract); + } - if (sig_len > pubkeydata_len) { - unsigned char *newpacket; - /* Should *NEVER* happen, but...well.. better safe than sorry */ - newpacket = LIBSSH2_REALLOC(session, packet, packet_len + 4 + (4 + method_len) + (4 + sig_len)); /* PK sigblob */ - if (!newpacket) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating additional space for userauth-hostbased packet", 0); - LIBSSH2_FREE(session, sig); - LIBSSH2_FREE(session, packet); - LIBSSH2_FREE(session, method); - return -1; - } - packet = newpacket; - } + if (sig_len > pubkeydata_len) { + unsigned char *newpacket; + /* Should *NEVER* happen, but...well.. better safe than sorry */ + newpacket = LIBSSH2_REALLOC(session, packet, packet_len + 4 + (4 + method_len) + (4 + sig_len)); /* PK sigblob */ + if (!newpacket) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating additional space for userauth-hostbased packet", 0); + LIBSSH2_FREE(session, sig); + LIBSSH2_FREE(session, packet); + LIBSSH2_FREE(session, method); + return -1; + } + packet = newpacket; + } - s = packet + packet_len; + s = packet + packet_len; - libssh2_htonu32(s, 4 + method_len + 4 + sig_len); s += 4; + libssh2_htonu32(s, 4 + method_len + 4 + sig_len); s += 4; - libssh2_htonu32(s, method_len); s += 4; - memcpy(s, method, method_len); s += method_len; - LIBSSH2_FREE(session, method); + libssh2_htonu32(s, method_len); s += 4; + memcpy(s, method, method_len); s += method_len; + LIBSSH2_FREE(session, method); - libssh2_htonu32(s, sig_len); s += 4; - memcpy(s, sig, sig_len); s += sig_len; - LIBSSH2_FREE(session, sig); + libssh2_htonu32(s, sig_len); s += 4; + memcpy(s, sig, sig_len); s += sig_len; + LIBSSH2_FREE(session, sig); - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting hostbased authentication"); - if (libssh2_packet_write(session, packet, s - packet)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-hostbased request", 0); - LIBSSH2_FREE(session, packet); - return -1; - } - LIBSSH2_FREE(session, packet); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting hostbased authentication"); + if (libssh2_packet_write(session, packet, s - packet)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-hostbased request", 0); + LIBSSH2_FREE(session, packet); + return -1; + } + LIBSSH2_FREE(session, packet); - if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { - return -1; - } + if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { + return -1; + } - if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, - "Hostbased authentication successful"); - /* We are us and we've proved it. */ - LIBSSH2_FREE(session, data); - session->state |= LIBSSH2_STATE_AUTHENTICATED; - return 0; - } + if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_DBG_AUTH, + "Hostbased authentication successful"); + /* We are us and we've proved it. */ + LIBSSH2_FREE(session, data); + session->state |= LIBSSH2_STATE_AUTHENTICATED; + return 0; + } - /* This public key is not allowed for this user on this server */ - LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid signature for supplied public key, or bad username/public key combination", 0); - return -1; + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, data); + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid signature for supplied public key, or bad username/public key combination", 0); + return -1; } /* }}} */ @@ -493,169 +493,169 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *publickey, const char *privatekey, const char *passphrase) { - const LIBSSH2_HOSTKEY_METHOD *privkeyobj; - void *abstract; - unsigned char buf[5]; - struct iovec datavec[4]; - unsigned char *method, *pubkeydata, *packet, *s, *b, *sig, *data; - unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PK_OK, 0 }; - unsigned long method_len, pubkeydata_len, packet_len, sig_len, data_len; + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + void *abstract; + unsigned char buf[5]; + struct iovec datavec[4]; + unsigned char *method, *pubkeydata, *packet, *s, *b, *sig, *data; + unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PK_OK, 0 }; + unsigned long method_len, pubkeydata_len, packet_len, sig_len, data_len; - if (libssh2_file_read_publickey(session, &method, &method_len, &pubkeydata, &pubkeydata_len, publickey)) { - return -1; - } + if (libssh2_file_read_publickey(session, &method, &method_len, &pubkeydata, &pubkeydata_len, publickey)) { + return -1; + } - packet_len = username_len + method_len + pubkeydata_len + 45; /* packet_type(1) + username_len(4) + servicename_len(4) + - service_name(14)"ssh-connection" + authmethod_len(4) + - authmethod(9)"publickey" + sig_included(1)'\0' + - algmethod_len(4) + publickey_len(4) */ - /* Preallocate space for an overall length, method name again, - * and the signature, which won't be any larger than the size of the publickeydata itself */ - s = packet = LIBSSH2_ALLOC(session, packet_len + 4 + (4 + method_len) + (4 + pubkeydata_len)); - if (!packet) { - LIBSSH2_FREE(session, method); - LIBSSH2_FREE(session, pubkeydata); - return -1; - } + packet_len = username_len + method_len + pubkeydata_len + 45; /* packet_type(1) + username_len(4) + servicename_len(4) + + service_name(14)"ssh-connection" + authmethod_len(4) + + authmethod(9)"publickey" + sig_included(1)'\0' + + algmethod_len(4) + publickey_len(4) */ + /* Preallocate space for an overall length, method name again, + * and the signature, which won't be any larger than the size of the publickeydata itself */ + s = packet = LIBSSH2_ALLOC(session, packet_len + 4 + (4 + method_len) + (4 + pubkeydata_len)); + if (!packet) { + LIBSSH2_FREE(session, method); + LIBSSH2_FREE(session, pubkeydata); + return -1; + } - *(s++) = SSH_MSG_USERAUTH_REQUEST; - libssh2_htonu32(s, username_len); s += 4; - memcpy(s, username, username_len); s += username_len; + *(s++) = SSH_MSG_USERAUTH_REQUEST; + libssh2_htonu32(s, username_len); s += 4; + memcpy(s, username, username_len); s += username_len; - libssh2_htonu32(s, 14); s += 4; - memcpy(s, "ssh-connection", 14); s += 14; + libssh2_htonu32(s, 14); s += 4; + memcpy(s, "ssh-connection", 14); s += 14; - libssh2_htonu32(s, 9); s += 4; - memcpy(s, "publickey", 9); s += 9; + libssh2_htonu32(s, 9); s += 4; + memcpy(s, "publickey", 9); s += 9; - b = s; - *(s++) = 0; /* Not sending signature with *this* packet */ + b = s; + *(s++) = 0; /* Not sending signature with *this* packet */ - libssh2_htonu32(s, method_len); s += 4; - memcpy(s, method, method_len); s += method_len; + libssh2_htonu32(s, method_len); s += 4; + memcpy(s, method, method_len); s += method_len; - libssh2_htonu32(s, pubkeydata_len); s += 4; - memcpy(s, pubkeydata, pubkeydata_len); s += pubkeydata_len; - LIBSSH2_FREE(session, pubkeydata); + libssh2_htonu32(s, pubkeydata_len); s += 4; + memcpy(s, pubkeydata, pubkeydata_len); s += pubkeydata_len; + LIBSSH2_FREE(session, pubkeydata); - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication"); - if (libssh2_packet_write(session, packet, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0); - LIBSSH2_FREE(session, packet); - LIBSSH2_FREE(session, method); - return -1; - } + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication"); + if (libssh2_packet_write(session, packet, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0); + LIBSSH2_FREE(session, packet); + LIBSSH2_FREE(session, method); + return -1; + } - if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { - LIBSSH2_FREE(session, packet); - LIBSSH2_FREE(session, method); - return -1; - } + if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { + LIBSSH2_FREE(session, packet); + LIBSSH2_FREE(session, method); + return -1; + } - if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Pubkey authentication prematurely successful"); - /* God help any SSH server that allows an UNVERIFIED public key to validate the user */ - LIBSSH2_FREE(session, data); - LIBSSH2_FREE(session, packet); - LIBSSH2_FREE(session, method); - session->state |= LIBSSH2_STATE_AUTHENTICATED; - return 0; - } + if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Pubkey authentication prematurely successful"); + /* God help any SSH server that allows an UNVERIFIED public key to validate the user */ + LIBSSH2_FREE(session, data); + LIBSSH2_FREE(session, packet); + LIBSSH2_FREE(session, method); + session->state |= LIBSSH2_STATE_AUTHENTICATED; + return 0; + } - if (data[0] == SSH_MSG_USERAUTH_FAILURE) { - /* This public key is not allowed for this user on this server */ - LIBSSH2_FREE(session, data); - LIBSSH2_FREE(session, packet); - LIBSSH2_FREE(session, method); - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED, "Username/PublicKey combination invalid", 0); - return -1; - } + if (data[0] == SSH_MSG_USERAUTH_FAILURE) { + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, data); + LIBSSH2_FREE(session, packet); + LIBSSH2_FREE(session, method); + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED, "Username/PublicKey combination invalid", 0); + return -1; + } - /* Semi-Success! */ - LIBSSH2_FREE(session, data); + /* Semi-Success! */ + LIBSSH2_FREE(session, data); - if (libssh2_file_read_privatekey(session, &privkeyobj, &abstract, method, method_len, privatekey, passphrase)) { - LIBSSH2_FREE(session, method); - LIBSSH2_FREE(session, packet); - return -1; - } + if (libssh2_file_read_privatekey(session, &privkeyobj, &abstract, method, method_len, privatekey, passphrase)) { + LIBSSH2_FREE(session, method); + LIBSSH2_FREE(session, packet); + return -1; + } - *b = 0xFF; + *b = 0xFF; - libssh2_htonu32(buf, session->session_id_len); - datavec[0].iov_base = buf; - datavec[0].iov_len = 4; - datavec[1].iov_base = session->session_id; - datavec[1].iov_len = session->session_id_len; - datavec[2].iov_base = packet; - datavec[2].iov_len = packet_len; + libssh2_htonu32(buf, session->session_id_len); + datavec[0].iov_base = buf; + datavec[0].iov_len = 4; + datavec[1].iov_base = session->session_id; + datavec[1].iov_len = session->session_id_len; + datavec[2].iov_base = packet; + datavec[2].iov_len = packet_len; - if (privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) { - LIBSSH2_FREE(session, method); - LIBSSH2_FREE(session, packet); - if (privkeyobj->dtor) { - privkeyobj->dtor(session, &abstract); - } - return -1; - } + if (privkeyobj->signv(session, &sig, &sig_len, 3, datavec, &abstract)) { + LIBSSH2_FREE(session, method); + LIBSSH2_FREE(session, packet); + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &abstract); + } + return -1; + } - if (privkeyobj->dtor) { - privkeyobj->dtor(session, &abstract); - } + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &abstract); + } - if (sig_len > pubkeydata_len) { - unsigned char *newpacket; - /* Should *NEVER* happen, but...well.. better safe than sorry */ - newpacket = LIBSSH2_REALLOC(session, packet, packet_len + 4 + (4 + method_len) + (4 + sig_len)); /* PK sigblob */ - if (!newpacket) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating additional space for userauth-publickey packet", 0); - LIBSSH2_FREE(session, sig); - LIBSSH2_FREE(session, packet); - LIBSSH2_FREE(session, method); - return -1; - } - packet = newpacket; - } + if (sig_len > pubkeydata_len) { + unsigned char *newpacket; + /* Should *NEVER* happen, but...well.. better safe than sorry */ + newpacket = LIBSSH2_REALLOC(session, packet, packet_len + 4 + (4 + method_len) + (4 + sig_len)); /* PK sigblob */ + if (!newpacket) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating additional space for userauth-publickey packet", 0); + LIBSSH2_FREE(session, sig); + LIBSSH2_FREE(session, packet); + LIBSSH2_FREE(session, method); + return -1; + } + packet = newpacket; + } - s = packet + packet_len; + s = packet + packet_len; - libssh2_htonu32(s, 4 + method_len + 4 + sig_len); s += 4; + libssh2_htonu32(s, 4 + method_len + 4 + sig_len); s += 4; - libssh2_htonu32(s, method_len); s += 4; - memcpy(s, method, method_len); s += method_len; - LIBSSH2_FREE(session, method); + libssh2_htonu32(s, method_len); s += 4; + memcpy(s, method, method_len); s += method_len; + LIBSSH2_FREE(session, method); - libssh2_htonu32(s, sig_len); s += 4; - memcpy(s, sig, sig_len); s += sig_len; - LIBSSH2_FREE(session, sig); + libssh2_htonu32(s, sig_len); s += 4; + memcpy(s, sig, sig_len); s += sig_len; + LIBSSH2_FREE(session, sig); - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication -- phase 2"); - if (libssh2_packet_write(session, packet, s - packet)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0); - LIBSSH2_FREE(session, packet); - return -1; - } - LIBSSH2_FREE(session, packet); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication -- phase 2"); + if (libssh2_packet_write(session, packet, s - packet)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0); + LIBSSH2_FREE(session, packet); + return -1; + } + LIBSSH2_FREE(session, packet); - /* PK_OK is no longer valid */ - reply_codes[2] = 0; + /* PK_OK is no longer valid */ + reply_codes[2] = 0; - if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { - return -1; - } + if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { + return -1; + } - if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Publickey authentication successful"); - /* We are us and we've proved it. */ - LIBSSH2_FREE(session, data); - session->state |= LIBSSH2_STATE_AUTHENTICATED; - return 0; - } + if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Publickey authentication successful"); + /* We are us and we've proved it. */ + LIBSSH2_FREE(session, data); + session->state |= LIBSSH2_STATE_AUTHENTICATED; + return 0; + } - /* This public key is not allowed for this user on this server */ - LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid signature for supplied public key, or bad username/public key combination", 0); - return -1; + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, data); + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid signature for supplied public key, or bad username/public key combination", 0); + return -1; } /* }}} */ @@ -663,193 +663,193 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, * Authenticate using a challenge-response authentication */ LIBSSH2_API int libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *username, unsigned int username_len, - LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))) + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))) { - unsigned char *s, *data; /* packet */ - unsigned long packet_len; + unsigned char *s, *data; /* packet */ + unsigned long packet_len; - packet_len = 1 /* byte SSH_MSG_USERAUTH_REQUEST */ - + 4 + username_len /* string user name (ISO-10646 UTF-8, as defined in [RFC-3629]) */ - + 4 + 14 /* string service name (US-ASCII) */ - + 4 + 20 /* string "keyboard-interactive" (US-ASCII) */ - + 4 + 0 /* string language tag (as defined in [RFC-3066]) */ - + 4 + 0 /* string submethods (ISO-10646 UTF-8) */ - ; + packet_len = 1 /* byte SSH_MSG_USERAUTH_REQUEST */ + + 4 + username_len /* string user name (ISO-10646 UTF-8, as defined in [RFC-3629]) */ + + 4 + 14 /* string service name (US-ASCII) */ + + 4 + 20 /* string "keyboard-interactive" (US-ASCII) */ + + 4 + 0 /* string language tag (as defined in [RFC-3066]) */ + + 4 + 0 /* string submethods (ISO-10646 UTF-8) */ + ; - if (!(data = s = LIBSSH2_ALLOC(session, packet_len))) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive authentication", 0); - return -1; - } + if (!(data = s = LIBSSH2_ALLOC(session, packet_len))) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive authentication", 0); + return -1; + } - *s++ = SSH_MSG_USERAUTH_REQUEST; + *s++ = SSH_MSG_USERAUTH_REQUEST; - /* user name */ - libssh2_htonu32(s, username_len); s += 4; - memcpy(s, username, username_len); s += username_len; + /* user name */ + libssh2_htonu32(s, username_len); s += 4; + memcpy(s, username, username_len); s += username_len; - /* service name */ - libssh2_htonu32(s, sizeof("ssh-connection") - 1); s += 4; - memcpy(s, "ssh-connection", sizeof("ssh-connection") - 1); s += sizeof("ssh-connection") - 1; + /* service name */ + libssh2_htonu32(s, sizeof("ssh-connection") - 1); s += 4; + memcpy(s, "ssh-connection", sizeof("ssh-connection") - 1); s += sizeof("ssh-connection") - 1; - /* "keyboard-interactive" */ - libssh2_htonu32(s, sizeof("keyboard-interactive") - 1); s += 4; - memcpy(s, "keyboard-interactive", sizeof("keyboard-interactive") - 1); s += sizeof("keyboard-interactive") - 1; + /* "keyboard-interactive" */ + libssh2_htonu32(s, sizeof("keyboard-interactive") - 1); s += 4; + memcpy(s, "keyboard-interactive", sizeof("keyboard-interactive") - 1); s += sizeof("keyboard-interactive") - 1; - /* language tag */ - libssh2_htonu32(s, 0); s += 4; + /* language tag */ + libssh2_htonu32(s, 0); s += 4; - /* submethods */ - libssh2_htonu32(s, 0); s += 4; + /* submethods */ + libssh2_htonu32(s, 0); s += 4; - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting keyboard-interactive authentication"); - if (libssh2_packet_write(session, data, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send keyboard-interactive request", 0); - LIBSSH2_FREE(session, data); - return -1; - } - LIBSSH2_FREE(session, data); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting keyboard-interactive authentication"); + if (libssh2_packet_write(session, data, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send keyboard-interactive request", 0); + LIBSSH2_FREE(session, data); + return -1; + } + LIBSSH2_FREE(session, data); - for (;;) { - static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0 }; - unsigned int auth_name_len; - char* auth_name = NULL; - unsigned auth_instruction_len; - char* auth_instruction = NULL; - unsigned int language_tag_len; - unsigned long data_len; - unsigned int num_prompts = 0; - unsigned int i; - int auth_failure = 1; - LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts = NULL; - LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses = NULL; + for (;;) { + static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0 }; + unsigned int auth_name_len; + char* auth_name = NULL; + unsigned auth_instruction_len; + char* auth_instruction = NULL; + unsigned int language_tag_len; + unsigned long data_len; + unsigned int num_prompts = 0; + unsigned int i; + int auth_failure = 1; + LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts = NULL; + LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses = NULL; - if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { - return -1; - } + if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) { + return -1; + } - if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive authentication successful"); - LIBSSH2_FREE(session, data); - session->state |= LIBSSH2_STATE_AUTHENTICATED; - return 0; - } + if (data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive authentication successful"); + LIBSSH2_FREE(session, data); + session->state |= LIBSSH2_STATE_AUTHENTICATED; + return 0; + } - if (data[0] == SSH_MSG_USERAUTH_FAILURE) { - LIBSSH2_FREE(session, data); - return -1; - } + if (data[0] == SSH_MSG_USERAUTH_FAILURE) { + LIBSSH2_FREE(session, data); + return -1; + } - /* server requested PAM-like conversation */ + /* server requested PAM-like conversation */ - s = data + 1; + s = data + 1; - /* string name (ISO-10646 UTF-8) */ - auth_name_len = libssh2_ntohu32(s); s += 4; - if (!(auth_name = LIBSSH2_ALLOC(session, auth_name_len))) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive 'name' request field", 0); - goto cleanup; - } - memcpy(auth_name, s, auth_name_len); s += auth_name_len; + /* string name (ISO-10646 UTF-8) */ + auth_name_len = libssh2_ntohu32(s); s += 4; + if (!(auth_name = LIBSSH2_ALLOC(session, auth_name_len))) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive 'name' request field", 0); + goto cleanup; + } + memcpy(auth_name, s, auth_name_len); s += auth_name_len; - /* string instruction (ISO-10646 UTF-8) */ - auth_instruction_len = libssh2_ntohu32(s); s += 4; - if (!(auth_instruction = LIBSSH2_ALLOC(session, auth_instruction_len))) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive 'instruction' request field", 0); - goto cleanup; - } - memcpy(auth_instruction, s, auth_instruction_len); s += auth_instruction_len; + /* string instruction (ISO-10646 UTF-8) */ + auth_instruction_len = libssh2_ntohu32(s); s += 4; + if (!(auth_instruction = LIBSSH2_ALLOC(session, auth_instruction_len))) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive 'instruction' request field", 0); + goto cleanup; + } + memcpy(auth_instruction, s, auth_instruction_len); s += auth_instruction_len; - /* string language tag (as defined in [RFC-3066]) */ - language_tag_len = libssh2_ntohu32(s); s += 4; - /* ignoring this field as deprecated */ s += language_tag_len; + /* string language tag (as defined in [RFC-3066]) */ + language_tag_len = libssh2_ntohu32(s); s += 4; + /* ignoring this field as deprecated */ s += language_tag_len; - /* int num-prompts */ - num_prompts = libssh2_ntohu32(s); s += 4; + /* int num-prompts */ + num_prompts = libssh2_ntohu32(s); s += 4; - prompts = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * num_prompts); - if (!prompts) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive prompts array", 0); - goto cleanup; - } - memset(prompts, 0, sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * num_prompts); + prompts = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * num_prompts); + if (!prompts) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive prompts array", 0); + goto cleanup; + } + memset(prompts, 0, sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * num_prompts); - responses = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * num_prompts); - if (!responses) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive responses array", 0); - goto cleanup; - } - memset(responses, 0, sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * num_prompts); + responses = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * num_prompts); + if (!responses) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive responses array", 0); + goto cleanup; + } + memset(responses, 0, sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * num_prompts); - for(i = 0; i != num_prompts; ++i) { - /* string prompt[1] (ISO-10646 UTF-8) */ - prompts[i].length = libssh2_ntohu32(s); s += 4; - if (!(prompts[i].text = LIBSSH2_ALLOC(session, prompts[i].length))) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive prompt message", 0); - goto cleanup; - } - memcpy(prompts[i].text, s, prompts[i].length); s += prompts[i].length; + for(i = 0; i != num_prompts; ++i) { + /* string prompt[1] (ISO-10646 UTF-8) */ + prompts[i].length = libssh2_ntohu32(s); s += 4; + if (!(prompts[i].text = LIBSSH2_ALLOC(session, prompts[i].length))) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive prompt message", 0); + goto cleanup; + } + memcpy(prompts[i].text, s, prompts[i].length); s += prompts[i].length; - /* boolean echo[1] */ - prompts[i].echo = *s++; - } + /* boolean echo[1] */ + prompts[i].echo = *s++; + } - response_callback(auth_name, auth_name_len, auth_instruction, auth_instruction_len, num_prompts, prompts, responses, &session->abstract); + response_callback(auth_name, auth_name_len, auth_instruction, auth_instruction_len, num_prompts, prompts, responses, &session->abstract); - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive response callback function invoked"); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive response callback function invoked"); - packet_len = 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */ - + 4 /* int num-responses */ - ; + packet_len = 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */ + + 4 /* int num-responses */ + ; - for (i = 0; i != num_prompts; ++i) { - packet_len += 4 + responses[i].length; /* string response[1] (ISO-10646 UTF-8) */ - } + for (i = 0; i != num_prompts; ++i) { + packet_len += 4 + responses[i].length; /* string response[1] (ISO-10646 UTF-8) */ + } - if (!(data = s = LIBSSH2_ALLOC(session, packet_len))) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive response packet", 0); - goto cleanup; - } + if (!(data = s = LIBSSH2_ALLOC(session, packet_len))) { + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive response packet", 0); + goto cleanup; + } - *s = SSH_MSG_USERAUTH_INFO_RESPONSE; s++; - libssh2_htonu32(s, num_prompts); s += 4; + *s = SSH_MSG_USERAUTH_INFO_RESPONSE; s++; + libssh2_htonu32(s, num_prompts); s += 4; - for (i = 0; i != num_prompts; ++i) { - libssh2_htonu32(s, responses[i].length); s += 4; - memcpy(s, responses[i].text, responses[i].length); s += responses[i].length; - } + for (i = 0; i != num_prompts; ++i) { + libssh2_htonu32(s, responses[i].length); s += 4; + memcpy(s, responses[i].text, responses[i].length); s += responses[i].length; + } - if (libssh2_packet_write(session, data, packet_len)) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-keyboard-interactive request", 0); - goto cleanup; - } + if (libssh2_packet_write(session, data, packet_len)) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-keyboard-interactive request", 0); + goto cleanup; + } - auth_failure = 0; + auth_failure = 0; - cleanup: - /* It's safe to clean all the data here, because unallocated pointers - * are filled by zeroes - */ + cleanup: + /* It's safe to clean all the data here, because unallocated pointers + * are filled by zeroes + */ - LIBSSH2_FREE(session, data); + LIBSSH2_FREE(session, data); - if (prompts) { - for (i = 0; i != num_prompts; ++i) { - LIBSSH2_FREE(session, prompts[i].text); - } - } + if (prompts) { + for (i = 0; i != num_prompts; ++i) { + LIBSSH2_FREE(session, prompts[i].text); + } + } - if (responses) { - for (i = 0; i != num_prompts; ++i) { - LIBSSH2_FREE(session, responses[i].text); - } - } + if (responses) { + for (i = 0; i != num_prompts; ++i) { + LIBSSH2_FREE(session, responses[i].text); + } + } - LIBSSH2_FREE(session, prompts); - LIBSSH2_FREE(session, responses); + LIBSSH2_FREE(session, prompts); + LIBSSH2_FREE(session, responses); - if (auth_failure) { - return -1; - } - } + if (auth_failure) { + return -1; + } + } } /* }}} */