diff --git a/src/channel.c b/src/channel.c index 7bed9d9..f996fac 100644 --- a/src/channel.c +++ b/src/channel.c @@ -48,7 +48,8 @@ /* {{{ libssh2_channel_nextid * Determine the next channel ID we can use at our end */ -unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session) +unsigned long +libssh2_channel_nextid(LIBSSH2_SESSION * session) { unsigned long id = session->next_channel; LIBSSH2_CHANNEL *channel; @@ -68,15 +69,18 @@ unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session) * 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); + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Allocated new channel ID#%lu", + id); return id; } + /* }}} */ /* {{{ libssh2_channel_locate * Locate a channel pointer by number */ -LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id) +LIBSSH2_CHANNEL * +libssh2_channel_locate(LIBSSH2_SESSION * session, unsigned long channel_id) { LIBSSH2_CHANNEL *channel = session->channels.head; while (channel) { @@ -88,6 +92,7 @@ LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long return NULL; } + /* }}} */ #define libssh2_channel_add(session, channel) \ @@ -108,8 +113,10 @@ LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long * Establish a generic session channel */ 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) +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) { static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, @@ -128,65 +135,83 @@ libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsi session->open_local_channel = libssh2_channel_nextid(session); /* Zero the whole thing out */ - memset(&session->open_packet_requirev_state, 0, sizeof(session->open_packet_requirev_state)); + memset(&session->open_packet_requirev_state, 0, + sizeof(session->open_packet_requirev_state)); - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Opening Channel - win %d pack %d", window_size, packet_size); - session->open_channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Opening Channel - win %d pack %d", window_size, + packet_size); + session->open_channel = + LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); if (!session->open_channel) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate space for channel data", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate space for channel data", 0); return NULL; } memset(session->open_channel, 0, sizeof(LIBSSH2_CHANNEL)); session->open_channel->channel_type_len = channel_type_len; - session->open_channel->channel_type = LIBSSH2_ALLOC(session, channel_type_len); + session->open_channel->channel_type = + LIBSSH2_ALLOC(session, channel_type_len); if (!session->open_channel->channel_type) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Failed allocating memory for channel type name", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating memory for channel type name", 0); LIBSSH2_FREE(session, session->open_channel); session->open_channel = NULL; return NULL; } - memcpy(session->open_channel->channel_type, channel_type, channel_type_len); + memcpy(session->open_channel->channel_type, channel_type, + channel_type_len); /* REMEMBER: local as in locally sourced */ - session->open_channel->local.id = session->open_local_channel; - session->open_channel->remote.window_size = window_size; - session->open_channel->remote.window_size_initial = window_size; - session->open_channel->remote.packet_size = packet_size; + session->open_channel->local.id = session->open_local_channel; + session->open_channel->remote.window_size = window_size; + session->open_channel->remote.window_size_initial = window_size; + session->open_channel->remote.packet_size = packet_size; libssh2_channel_add(session, session->open_channel); - s = session->open_packet = LIBSSH2_ALLOC(session, session->open_packet_len); + s = session->open_packet = + LIBSSH2_ALLOC(session, session->open_packet_len); if (!session->open_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate temporary space for packet", 0); + 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; + 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, session->open_local_channel); s += 4; + libssh2_htonu32(s, session->open_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; + memcpy(s, message, message_len); + s += message_len; } session->open_state = libssh2_NB_state_created; } if (session->open_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, session->open_packet, session->open_packet_len); + rc = libssh2_packet_write(session, session->open_packet, + session->open_packet_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending channel-open request", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending channel-open request", 0); return NULL; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel-open request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel-open request", 0); goto channel_error; } @@ -194,25 +219,36 @@ libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsi } if (session->open_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &session->open_data, &session->open_data_len, 1, - session->open_packet + 5 + channel_type_len, 4, &session->open_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, + &session->open_data, + &session->open_data_len, 1, + session->open_packet + 5 + + channel_type_len, 4, + &session->open_packet_requirev_state); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block", 0); return NULL; - } - else if (rc) { + } else if (rc) { goto channel_error; } if (session->open_data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) { - session->open_channel->remote.id = libssh2_ntohu32(session->open_data + 5); - session->open_channel->local.window_size = libssh2_ntohu32(session->open_data + 9); - session->open_channel->local.window_size_initial = libssh2_ntohu32(session->open_data + 9); - session->open_channel->local.packet_size = libssh2_ntohu32(session->open_data + 13); - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Connection Established - ID: %lu/%lu win: %lu/%lu pack: %lu/%lu", - session->open_channel->local.id, session->open_channel->remote.id, - session->open_channel->local.window_size, session->open_channel->remote.window_size, - session->open_channel->local.packet_size, session->open_channel->remote.packet_size); + session->open_channel->remote.id = + libssh2_ntohu32(session->open_data + 5); + session->open_channel->local.window_size = + libssh2_ntohu32(session->open_data + 9); + session->open_channel->local.window_size_initial = + libssh2_ntohu32(session->open_data + 9); + session->open_channel->local.packet_size = + libssh2_ntohu32(session->open_data + 13); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Connection Established - ID: %lu/%lu win: %lu/%lu pack: %lu/%lu", + session->open_channel->local.id, + session->open_channel->remote.id, + session->open_channel->local.window_size, + session->open_channel->remote.window_size, + session->open_channel->local.packet_size, + session->open_channel->remote.packet_size); LIBSSH2_FREE(session, session->open_packet); session->open_packet = NULL; LIBSSH2_FREE(session, session->open_data); @@ -223,11 +259,12 @@ libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, unsi } if (session->open_data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Channel open failure", 0); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure", 0); } } -channel_error: + channel_error: if (session->open_data) { LIBSSH2_FREE(session, session->open_data); @@ -256,10 +293,13 @@ channel_error: /* Clear out packets meant for this channel */ libssh2_htonu32(channel_id, session->open_channel->local.id); - while ((libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_DATA, &session->open_data, &session->open_data_len, - 1, channel_id, 4, 0) >= 0) || - (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &session->open_data, &session->open_data_len, - 1, channel_id, 4, 0) >= 0)) { + while ((libssh2_packet_ask_ex + (session, SSH_MSG_CHANNEL_DATA, &session->open_data, + &session->open_data_len, 1, channel_id, 4, 0) >= 0) + || + (libssh2_packet_ask_ex + (session, SSH_MSG_CHANNEL_EXTENDED_DATA, &session->open_data, + &session->open_data_len, 1, channel_id, 4, 0) >= 0)) { LIBSSH2_FREE(session, session->open_data); session->open_data = NULL; } @@ -277,13 +317,15 @@ channel_error: session->open_state = libssh2_NB_state_idle; return NULL; } + /* }}} */ /* {{{ libssh2_channel_direct_tcpip_ex * Tunnel TCP/IP connect through the SSH session to direct host/port */ LIBSSH2_API LIBSSH2_CHANNEL * -libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int port, const char *shost, int sport) +libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION * session, const char *host, + int port, const char *shost, int sport) { LIBSSH2_CHANNEL *channel; unsigned char *s; @@ -292,29 +334,45 @@ libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int session->direct_host_len = strlen(host); session->direct_shost_len = strlen(shost); /* host_len(4) + port(4) + shost_len(4) + sport(4) */ - session->direct_message_len = session->direct_host_len + session->direct_shost_len + 16; + session->direct_message_len = + session->direct_host_len + session->direct_shost_len + 16; - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Requesting direct-tcpip session to from %s:%d to %s:%d", + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Requesting direct-tcpip session to from %s:%d to %s:%d", shost, sport, host, port); - s = session->direct_message = LIBSSH2_ALLOC(session, session->direct_message_len); + s = session->direct_message = + LIBSSH2_ALLOC(session, session->direct_message_len); if (!session->direct_message) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for direct-tcpip connection", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for direct-tcpip connection", + 0); return NULL; } - libssh2_htonu32(s, session->direct_host_len); s += 4; - memcpy(s, host, session->direct_host_len); s += session->direct_host_len; - libssh2_htonu32(s, port); s += 4; + libssh2_htonu32(s, session->direct_host_len); + s += 4; + memcpy(s, host, session->direct_host_len); + s += session->direct_host_len; + libssh2_htonu32(s, port); + s += 4; - libssh2_htonu32(s, session->direct_shost_len); s += 4; - memcpy(s, shost, session->direct_shost_len); s += session->direct_shost_len; - libssh2_htonu32(s, sport); s += 4; + libssh2_htonu32(s, session->direct_shost_len); + s += 4; + memcpy(s, shost, session->direct_shost_len); + s += session->direct_shost_len; + libssh2_htonu32(s, sport); + s += 4; session->direct_state = libssh2_NB_state_created; } - channel = libssh2_channel_open_ex(session, "direct-tcpip", sizeof("direct-tcpip") - 1, LIBSSH2_CHANNEL_WINDOW_DEFAULT, - LIBSSH2_CHANNEL_PACKET_DEFAULT, (char *)session->direct_message, session->direct_message_len); + channel = + libssh2_channel_open_ex(session, "direct-tcpip", + sizeof("direct-tcpip") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, + (char *) session->direct_message, + session->direct_message_len); if (!channel) { if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { /* The error code is still set to LIBSSH2_ERROR_EAGAIN */ @@ -331,55 +389,74 @@ libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, int return channel; } + /* }}} */ /* {{{ libssh2_channel_forward_listen_ex * Bind a port on the remote host and listen for connections */ LIBSSH2_API LIBSSH2_LISTENER * -libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, int port, int *bound_port, int queue_maxsize) +libssh2_channel_forward_listen_ex(LIBSSH2_SESSION * session, const char *host, + int port, int *bound_port, int queue_maxsize) { unsigned char *s, *data; - static const unsigned char reply_codes[3] = { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 }; + static const unsigned char reply_codes[3] = + { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 }; unsigned long data_len; int rc; if (session->fwdLstn_state == libssh2_NB_state_idle) { - session->fwdLstn_host_len = (host ? strlen(host) : (sizeof("0.0.0.0") - 1)); + session->fwdLstn_host_len = + (host ? strlen(host) : (sizeof("0.0.0.0") - 1)); /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */ - session->fwdLstn_packet_len = session->fwdLstn_host_len + (sizeof("tcpip-forward") - 1) + 14; + session->fwdLstn_packet_len = + session->fwdLstn_host_len + (sizeof("tcpip-forward") - 1) + 14; /* Zero the whole thing out */ - memset(&session->fwdLstn_packet_requirev_state, 0, sizeof(session->fwdLstn_packet_requirev_state)); + memset(&session->fwdLstn_packet_requirev_state, 0, + sizeof(session->fwdLstn_packet_requirev_state)); - _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 = session->fwdLstn_packet = LIBSSH2_ALLOC(session, session->fwdLstn_packet_len); + s = session->fwdLstn_packet = + LIBSSH2_ALLOC(session, session->fwdLstn_packet_len); if (!session->fwdLstn_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memeory for setenv packet", 0); + 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++) = 0x01; /* want_reply */ + libssh2_htonu32(s, sizeof("tcpip-forward") - 1); + s += 4; + memcpy(s, "tcpip-forward", sizeof("tcpip-forward") - 1); + s += sizeof("tcpip-forward") - 1; + *(s++) = 0x01; /* want_reply */ - libssh2_htonu32(s, session->fwdLstn_host_len); s += 4; - memcpy(s, host ? host : "0.0.0.0", session->fwdLstn_host_len); s += session->fwdLstn_host_len; - libssh2_htonu32(s, port); s += 4; + libssh2_htonu32(s, session->fwdLstn_host_len); + s += 4; + memcpy(s, host ? host : "0.0.0.0", session->fwdLstn_host_len); + s += session->fwdLstn_host_len; + libssh2_htonu32(s, port); + s += 4; session->fwdLstn_state = libssh2_NB_state_created; } if (session->fwdLstn_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, session->fwdLstn_packet, session->fwdLstn_packet_len); + rc = libssh2_packet_write(session, session->fwdLstn_packet, + session->fwdLstn_packet_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending global-request packet for forward listen request", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending global-request packet for forward listen request", + 0); return NULL; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send global-request packet for forward listen request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send global-request packet for forward listen request", + 0); LIBSSH2_FREE(session, session->fwdLstn_packet); session->fwdLstn_packet = NULL; session->fwdLstn_state = libssh2_NB_state_idle; @@ -392,13 +469,14 @@ libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, in } if (session->fwdLstn_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 0, NULL, 0, - &session->fwdLstn_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, + 0, NULL, 0, + &session-> + fwdLstn_packet_requirev_state); if (rc == PACKET_EAGAIN) { libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block", 0); return NULL; - } - else if (rc) { + } else if (rc) { libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unknown", 0); session->fwdLstn_state = libssh2_NB_state_idle; return NULL; @@ -409,26 +487,34 @@ libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, in listener = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_LISTENER)); if (!listener) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for listener queue", + 0); LIBSSH2_FREE(session, data); session->fwdLstn_state = libssh2_NB_state_idle; return NULL; } memset(listener, 0, sizeof(LIBSSH2_LISTENER)); listener->session = session; - listener->host = LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1); + listener->host = + LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1); if (!listener->host) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for listener queue", + 0); LIBSSH2_FREE(session, listener); LIBSSH2_FREE(session, data); session->fwdLstn_state = libssh2_NB_state_idle; return NULL; } - memcpy(listener->host, host ? host : "0.0.0.0", session->fwdLstn_host_len); + memcpy(listener->host, host ? host : "0.0.0.0", + session->fwdLstn_host_len); listener->host[session->fwdLstn_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); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Dynamic tcpip-forward port allocated: %d", + listener->port); } else { listener->port = port; } @@ -454,7 +540,8 @@ libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, in 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); + libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED, + "Unable to complete request for forward-listen", 0); session->fwdLstn_state = libssh2_NB_state_idle; return NULL; } @@ -464,6 +551,7 @@ libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, in return NULL; } + /* }}} */ /* {{{ libssh2_channel_forward_cancel @@ -472,33 +560,43 @@ libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, in * * Return 0 on success, PACKET_EAGAIN if would block, -1 on error */ -LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) +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); /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */ - unsigned long packet_len = host_len + 14 + sizeof("cancel-tcpip-forward") - 1; + unsigned long packet_len = + host_len + 14 + sizeof("cancel-tcpip-forward") - 1; int rc; if (listener->chanFwdCncl_state == libssh2_NB_state_idle) { - _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); + 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 */ + 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; listener->chanFwdCncl_state = libssh2_NB_state_created; } else { @@ -509,15 +607,16 @@ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) rc = libssh2_packet_write(session, packet, packet_len); if (rc == PACKET_EAGAIN) { listener->chanFwdCncl_data = packet; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send global-request packet for forward listen request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send global-request packet for forward listen request", + 0); LIBSSH2_FREE(session, packet); listener->chanFwdCncl_state = libssh2_NB_state_idle; return -1; } LIBSSH2_FREE(session, packet); - + listener->chanFwdCncl_state = libssh2_NB_state_sent; } @@ -544,23 +643,25 @@ LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) LIBSSH2_FREE(session, listener); listener->chanFwdCncl_state = libssh2_NB_state_idle; - + return 0; } + /* }}} */ /* {{{ libssh2_channel_forward_accept * Accept a connection */ LIBSSH2_API LIBSSH2_CHANNEL * -libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener) +libssh2_channel_forward_accept(LIBSSH2_LISTENER * listener) { libssh2pack_t rc; do { rc = libssh2_packet_read(listener->session); if (rc == PACKET_EAGAIN) { - libssh2_error(listener->session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for packet", 0); + libssh2_error(listener->session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for packet", 0); return NULL; } } while (rc > 0); @@ -592,18 +693,21 @@ libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener) return NULL; } + /* }}} */ /* {{{ libssh2_channel_setenv_ex * Set an environment variable prior to requesting a shell/program/subsystem */ LIBSSH2_API int -libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int varname_len, const char *value, +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, *data; - static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; unsigned long data_len; int rc; @@ -613,40 +717,53 @@ libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int channel->setenv_packet_len = varname_len + value_len + 21; /* Zero the whole thing out */ - memset(&channel->setenv_packet_requirev_state, 0, sizeof(channel->setenv_packet_requirev_state)); + memset(&channel->setenv_packet_requirev_state, 0, + sizeof(channel->setenv_packet_requirev_state)); - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Setting remote environment variable: %s=%s on channel %lu/%lu", + _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 = channel->setenv_packet = LIBSSH2_ALLOC(session, channel->setenv_packet_len); + s = channel->setenv_packet = + LIBSSH2_ALLOC(session, channel->setenv_packet_len); if (!channel->setenv_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memeory for setenv packet", 0); + 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; + 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++) = 0x01; - 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; channel->setenv_state = libssh2_NB_state_created; } if (channel->setenv_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, channel->setenv_packet, channel->setenv_packet_len); + rc = libssh2_packet_write(session, channel->setenv_packet, + channel->setenv_packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel-request packet for setenv request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel-request packet for setenv request", + 0); LIBSSH2_FREE(session, channel->setenv_packet); channel->setenv_packet = NULL; channel->setenv_state = libssh2_NB_state_idle; @@ -661,8 +778,10 @@ libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int } if (channel->setenv_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, channel->setenv_local_channel, 4, - &channel->setenv_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, + 1, channel->setenv_local_channel, 4, + &channel-> + setenv_packet_requirev_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; } @@ -680,22 +799,27 @@ libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, unsigned int LIBSSH2_FREE(session, data); } - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel-setenv", 0); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel-setenv", 0); channel->setenv_state = libssh2_NB_state_idle; return -1; } + /* }}} */ /* {{{ libssh2_channel_request_pty_ex * 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) +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) { LIBSSH2_SESSION *session = channel->session; unsigned char *s, *data; - static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; unsigned long data_len; int rc; @@ -706,48 +830,65 @@ libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsig channel->reqPTY_packet_len = term_len + modes_len + 41; /* Zero the whole thing out */ - memset(&channel->reqPTY_packet_requirev_state, 0, sizeof(channel->reqPTY_packet_requirev_state)); + memset(&channel->reqPTY_packet_requirev_state, 0, + sizeof(channel->reqPTY_packet_requirev_state)); - _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 = channel->reqPTY_packet = LIBSSH2_ALLOC(session, channel->reqPTY_packet_len); + s = channel->reqPTY_packet = + LIBSSH2_ALLOC(session, channel->reqPTY_packet_len); if (!channel->reqPTY_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for pty-request", 0); + 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; + 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++) = 0x01; - libssh2_htonu32(s, term_len); s += 4; + libssh2_htonu32(s, term_len); + s += 4; if (term) { - memcpy(s, term, term_len); s += term_len; + 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; + libssh2_htonu32(s, modes_len); + s += 4; if (modes) { - memcpy(s, modes, modes_len); s += modes_len; + memcpy(s, modes, modes_len); + s += modes_len; } channel->reqPTY_state = libssh2_NB_state_created; } if (channel->reqPTY_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, channel->reqPTY_packet, channel->reqPTY_packet_len); + rc = libssh2_packet_write(session, channel->reqPTY_packet, + channel->reqPTY_packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send pty-request packet", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send pty-request packet", 0); LIBSSH2_FREE(session, channel->reqPTY_packet); channel->reqPTY_packet = NULL; channel->reqPTY_state = libssh2_NB_state_idle; @@ -762,12 +903,13 @@ libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsig } if (channel->reqPTY_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, channel->reqPTY_local_channel, 4, - &channel->reqPTY_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, + 1, channel->reqPTY_local_channel, 4, + &channel-> + reqPTY_packet_requirev_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { channel->reqPTY_state = libssh2_NB_state_idle; return -1; } @@ -780,10 +922,12 @@ libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsig } LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel request-pty", 0); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel request-pty", 0); channel->reqPTY_state = libssh2_NB_state_idle; return -1; } + /* }}} */ /* Keep this an even number */ @@ -793,15 +937,19 @@ libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, unsig * 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, +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, *data; - static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + 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 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; int rc; if (channel->reqX11_state == libssh2_NB_state_idle) { @@ -814,29 +962,39 @@ libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, cons memset(&channel->reqX11_packet_requirev_state, 0, sizeof(channel->reqX11_packet_requirev_state)); - _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", + _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 = channel->reqX11_packet = LIBSSH2_ALLOC(session, channel->reqX11_packet_len); + s = channel->reqX11_packet = + LIBSSH2_ALLOC(session, channel->reqX11_packet_len); if (!channel->reqX11_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for pty-request", 0); + 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; + 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++) = 0x01; /* want_reply */ + *(s++) = 0x01; /* want_reply */ *(s++) = single_connection ? 0x01 : 0x00; - libssh2_htonu32(s, proto_len); s += 4; + libssh2_htonu32(s, proto_len); + s += 4; memcpy(s, auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", proto_len); - s += proto_len; + s += proto_len; - libssh2_htonu32(s, cookie_len); s += 4; + libssh2_htonu32(s, cookie_len); + s += 4; if (auth_cookie) { memcpy(s, auth_cookie, cookie_len); } else { @@ -844,24 +1002,27 @@ libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, cons 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]); + 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; channel->reqX11_state = libssh2_NB_state_created; } if (channel->reqX11_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, channel->reqX11_packet, channel->reqX11_packet_len); + rc = libssh2_packet_write(session, channel->reqX11_packet, + channel->reqX11_packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; } if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send x11-req packet", 0); + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send x11-req packet", 0); LIBSSH2_FREE(session, channel->reqX11_packet); channel->reqX11_packet = NULL; channel->reqX11_state = libssh2_NB_state_idle; @@ -876,12 +1037,13 @@ libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, cons } if (channel->reqX11_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, channel->reqX11_local_channel, 4, - &channel->reqX11_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, + 1, channel->reqX11_local_channel, 4, + &channel-> + reqX11_packet_requirev_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { channel->reqX11_state = libssh2_NB_state_idle; return -1; } @@ -894,65 +1056,81 @@ libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, cons } LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel x11-req", 0); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel x11-req", 0); return -1; } + /* }}} */ /* {{{ libssh2_channel_process_startup * Primitive for libssh2_channel_(shell|exec|subsystem) */ LIBSSH2_API int -libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, unsigned int request_len, const char *message, +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, *data; - static const unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; unsigned long data_len; libssh2pack_t rc; - if (channel->process_state == libssh2_NB_state_idle) { + if (channel->process_state == libssh2_NB_state_idle) { /* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */ channel->process_packet_len = request_len + 10; /* Zero the whole thing out */ - memset(&channel->process_packet_requirev_state, 0, sizeof(channel->process_packet_requirev_state)); + memset(&channel->process_packet_requirev_state, 0, + sizeof(channel->process_packet_requirev_state)); if (message) { channel->process_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 = channel->process_packet = LIBSSH2_ALLOC(session, channel->process_packet_len); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "starting request(%s) on channel %lu/%lu, message=%s", + request, channel->local.id, channel->remote.id, + message); + s = channel->process_packet = + LIBSSH2_ALLOC(session, channel->process_packet_len); if (!channel->process_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for channel-process request", 0); + 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; + libssh2_htonu32(s, channel->remote.id); + s += 4; + libssh2_htonu32(s, request_len); + s += 4; + memcpy(s, request, request_len); + s += request_len; *(s++) = 0x01; if (message) { - libssh2_htonu32(s, message_len); s += 4; - memcpy(s, message, message_len); s += message_len; + libssh2_htonu32(s, message_len); + s += 4; + memcpy(s, message, message_len); + s += message_len; } channel->process_state = libssh2_NB_state_created; } if (channel->process_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, channel->process_packet, channel->process_packet_len); + rc = libssh2_packet_write(session, channel->process_packet, + channel->process_packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel request", 0); LIBSSH2_FREE(session, channel->process_packet); channel->process_packet = NULL; channel->process_state = libssh2_NB_state_idle; @@ -967,12 +1145,13 @@ libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, u } if (channel->process_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, channel->process_local_channel, 4, - &channel->process_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, + 1, channel->process_local_channel, 4, + &channel-> + process_packet_requirev_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { channel->process_state = libssh2_NB_state_idle; return -1; } @@ -985,10 +1164,12 @@ libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, u } LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel-process-startup", 0); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel-process-startup", 0); channel->process_state = libssh2_NB_state_idle; return -1; } + /* }}} */ /* {{{ libssh2_channel_set_blocking @@ -996,17 +1177,19 @@ libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, const char *request, u * fcntl(fd, F_SETFL, O_NONBLOCK); type command */ LIBSSH2_API void -libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, int blocking) +libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking) { - (void)_libssh2_session_set_blocking(channel->session, blocking); + (void) _libssh2_session_set_blocking(channel->session, blocking); } + /* }}} */ /* {{{ libssh2_channel_flush_ex * Flush data from one (or all) stream * Returns number of bytes flushed, or -1 on failure */ -LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid) +LIBSSH2_API int +libssh2_channel_flush_ex(LIBSSH2_CHANNEL * channel, int streamid) { LIBSSH2_PACKET *packet = channel->session->packets.head; @@ -1018,18 +1201,26 @@ LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid) 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)) { + 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))) { + 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); + "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 */ channel->flush_refund_bytes += packet->data_len - 13; @@ -1058,7 +1249,9 @@ LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid) if (channel->flush_refund_bytes) { int rc; - rc = libssh2_channel_receive_window_adjust(channel, channel->flush_refund_bytes, 0); + rc = libssh2_channel_receive_window_adjust(channel, + channel->flush_refund_bytes, + 0); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; } @@ -1068,12 +1261,14 @@ LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int streamid) return channel->flush_flush_bytes; } + /* }}} */ /* {{{ libssh2_channel_get_exit_status * Return the channel's program exit status */ -LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel) +LIBSSH2_API int +libssh2_channel_get_exit_status(LIBSSH2_CHANNEL * channel) { return channel->exit_status; } @@ -1088,12 +1283,16 @@ LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel) * Returns the new size of the receive window (as understood by remote end) */ LIBSSH2_API unsigned long -libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long adjustment, unsigned char force) +libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, + unsigned long adjustment, + unsigned char force) { int rc; if (channel->adjust_state == libssh2_NB_state_idle) { - if (!force && (adjustment + channel->adjust_queue < LIBSSH2_CHANNEL_MINADJUST)) { + 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); @@ -1113,18 +1312,19 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long ad channel->adjust_adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST; libssh2_htonu32(channel->adjust_adjust + 1, channel->remote.id); libssh2_htonu32(channel->adjust_adjust + 5, adjustment); - _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Adjusting window %lu bytes for data flushed from channel %lu/%lu", + _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); - + channel->adjust_state = libssh2_NB_state_created; } rc = libssh2_packet_write(channel->session, channel->adjust_adjust, 9); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send transfer-window adjustment packet, deferring", + } else if (rc) { + libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send transfer-window adjustment packet, deferring", 0); channel->adjust_queue = adjustment; } else { @@ -1133,6 +1333,7 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long ad return channel->remote.window_size; } + /* }}} */ /* {{{ libssh2_channel_handle_extended_data @@ -1142,16 +1343,20 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, unsigned long ad * Ignore it entirely [toss out packets as they come in]? (IGNORE) */ LIBSSH2_API void -libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode) +libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL * channel, + int ignore_mode) { - while (libssh2_channel_handle_extended_data2(channel, ignore_mode) == PACKET_EAGAIN); + while (libssh2_channel_handle_extended_data2(channel, ignore_mode) == + PACKET_EAGAIN); } LIBSSH2_API int -libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, int ignore_mode) +libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL * channel, + int ignore_mode) { if (channel->extData2_state == libssh2_NB_state_idle) { - _libssh2_debug(channel->session, LIBSSH2_DBG_CONN, "Setting channel %lu/%lu handle_extended_data mode to %d", + _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; @@ -1160,7 +1365,9 @@ libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, int ignore_mode) if (channel->extData2_state == libssh2_NB_state_idle) { if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) { - if (libssh2_channel_flush_ex(channel, LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) == PACKET_EAGAIN) { + if (libssh2_channel_flush_ex + (channel, + LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) == PACKET_EAGAIN) { return PACKET_EAGAIN; } } @@ -1169,6 +1376,7 @@ libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, int ignore_mode) channel->extData2_state = libssh2_NB_state_idle; return 0; } + /* }}} */ /* @@ -1181,14 +1389,17 @@ libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, int ignore_mode) * PACKET_EAGAIN. */ LIBSSH2_API ssize_t -libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size_t buflen) +libssh2_channel_read_ex(LIBSSH2_CHANNEL * channel, int stream_id, char *buf, + size_t buflen) { LIBSSH2_SESSION *session = channel->session; libssh2pack_t rc = 0; if (channel->read_state == libssh2_NB_state_idle) { - _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); /* process all incoming packets */ do { @@ -1208,10 +1419,10 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size channel->read_block = 0; channel->read_packet = session->packets.head; - + channel->read_state = libssh2_NB_state_created; } - + /* * =============================== NOTE =============================== * I know this is very ugly and not a really good use of "goto", but @@ -1220,9 +1431,9 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size if (channel->read_state == libssh2_NB_state_jump1) { goto channel_read_ex_point1; } - + rc = 0; - + do { if (channel->read_block) { /* in the second lap and onwards, do this */ @@ -1238,11 +1449,13 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size return rc; } - while (channel->read_packet && (channel->read_bytes_read < (int)buflen)) { + while (channel->read_packet + && (channel->read_bytes_read < (int) buflen)) { /* In case packet gets destroyed during this iteration */ channel->read_next = channel->read_packet->next; - channel->read_local_id = libssh2_ntohu32(channel->read_packet->data + 1); + channel->read_local_id = + libssh2_ntohu32(channel->read_packet->data + 1); /* * Either we asked for a specific extended data stream @@ -1251,52 +1464,72 @@ libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, size * or the standard stream with extended_data_merge * enabled and data was available */ - if ((stream_id && (channel->read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && - (channel->local.id == channel->read_local_id) && - (stream_id == (int)libssh2_ntohu32(channel->read_packet->data + 5))) || - - (!stream_id && (channel->read_packet->data[0] == SSH_MSG_CHANNEL_DATA) && - (channel->local.id == channel->read_local_id)) || - - (!stream_id && (channel->read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && - (channel->local.id == channel->read_local_id) && - (channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { + if ((stream_id + && (channel->read_packet->data[0] == + SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == channel->read_local_id) + && (stream_id == + (int) libssh2_ntohu32(channel->read_packet->data + 5))) + || (!stream_id + && (channel->read_packet->data[0] == SSH_MSG_CHANNEL_DATA) + && (channel->local.id == channel->read_local_id)) + || (!stream_id + && (channel->read_packet->data[0] == + SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == channel->read_local_id) + && (channel->remote.extended_data_ignore_mode == + LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { channel->read_want = buflen - channel->read_bytes_read; channel->read_unlink_packet = 0; - if (channel->read_want >= (int)(channel->read_packet->data_len - channel->read_packet->data_head)) { - channel->read_want = channel->read_packet->data_len - channel->read_packet->data_head; + if (channel->read_want >= + (int) (channel->read_packet->data_len - + channel->read_packet->data_head)) { + channel->read_want = + channel->read_packet->data_len - + channel->read_packet->data_head; channel->read_unlink_packet = 1; } - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Reading %d of buffered data from %lu/%lu/%d", - channel->read_want, channel->local.id, channel->remote.id, stream_id); - memcpy(buf + channel->read_bytes_read, channel->read_packet->data + channel->read_packet->data_head, - channel->read_want); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Reading %d of buffered data from %lu/%lu/%d", + channel->read_want, channel->local.id, + channel->remote.id, stream_id); + memcpy(buf + channel->read_bytes_read, + channel->read_packet->data + + channel->read_packet->data_head, channel->read_want); channel->read_packet->data_head += channel->read_want; channel->read_bytes_read += channel->read_want; if (channel->read_unlink_packet) { if (channel->read_packet->prev) { - channel->read_packet->prev->next = channel->read_packet->next; + channel->read_packet->prev->next = + channel->read_packet->next; } else { session->packets.head = channel->read_packet->next; } if (channel->read_packet->next) { - channel->read_packet->next->prev = channel->read_packet->prev; + channel->read_packet->next->prev = + channel->read_packet->prev; } else { session->packets.tail = channel->read_packet->prev; } LIBSSH2_FREE(session, channel->read_packet->data); - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Unlinking empty packet buffer from channel %lu/%lu", + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Unlinking empty packet buffer from channel %lu/%lu", channel->local.id, channel->remote.id); -channel_read_ex_point1: + channel_read_ex_point1: channel->read_state = libssh2_NB_state_jump1; - rc = libssh2_channel_receive_window_adjust(channel, channel->read_packet->data_len - (stream_id ? 13 : 9), 0); - if (rc == PACKET_EAGAIN){ + rc = libssh2_channel_receive_window_adjust(channel, + channel-> + read_packet-> + data_len - + (stream_id ? 13 + : 9), 0); + if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; } channel->read_state = libssh2_NB_state_created; @@ -1312,7 +1545,8 @@ channel_read_ex_point1: channel->read_state = libssh2_NB_state_idle; if (channel->read_bytes_read == 0) { if (channel->session->socket_block) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_CLOSED, "Remote end has closed this channel", 0); + 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 @@ -1327,6 +1561,7 @@ channel_read_ex_point1: channel->read_state = libssh2_NB_state_idle; return channel->read_bytes_read; } + /* }}} */ /* @@ -1335,19 +1570,19 @@ channel_read_ex_point1: * isn't a packet. */ unsigned long -libssh2_channel_packet_data_len(LIBSSH2_CHANNEL *channel, int stream_id) +libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id) { LIBSSH2_SESSION *session = channel->session; LIBSSH2_PACKET *read_packet; uint32_t read_local_id; - + if ((read_packet = session->packets.head) == NULL) { return 0; } - + while (read_packet) { read_local_id = libssh2_ntohu32(read_packet->data + 1); - + /* * Either we asked for a specific extended data stream * (and data was available), @@ -1355,30 +1590,41 @@ libssh2_channel_packet_data_len(LIBSSH2_CHANNEL *channel, int stream_id) * or the standard stream with extended_data_merge * enabled and data was available */ - if ((stream_id && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && - (channel->local.id == read_local_id) && - (stream_id == (int)libssh2_ntohu32(read_packet->data + 5))) || - - (!stream_id && (read_packet->data[0] == SSH_MSG_CHANNEL_DATA) && - (channel->local.id == read_local_id)) || - - (!stream_id && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) && - (channel->local.id == read_local_id) && - (channel->remote.extended_data_ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { - + if ((stream_id + && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == read_local_id) + && (stream_id == (int) libssh2_ntohu32(read_packet->data + 5))) + || (!stream_id && (read_packet->data[0] == SSH_MSG_CHANNEL_DATA) + && (channel->local.id == read_local_id)) || (!stream_id + && (read_packet-> + data[0] == + SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel-> + local.id == + read_local_id) + && (channel-> + remote. + extended_data_ignore_mode + == + LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) + { + return (read_packet->data_len - read_packet->data_head); } read_packet = read_packet->next; } - + return 0; } + /* }}} */ /* {{{ libssh2_channel_write_ex * Send data to a channel */ -LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, const char *buf, size_t buflen) +LIBSSH2_API ssize_t +libssh2_channel_write_ex(LIBSSH2_CHANNEL * channel, int stream_id, + const char *buf, size_t buflen) { LIBSSH2_SESSION *session = channel->session; libssh2pack_t rc; @@ -1386,16 +1632,21 @@ LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int strea if (channel->write_state == libssh2_NB_state_idle) { channel->write_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); + _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); + 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); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_EOF_SENT, + "EOF has already been sight, data might be ignored", + 0); } if (!channel->session->socket_block && @@ -1406,9 +1657,12 @@ LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int strea /* [13] 9 = packet_type(1) + channelno(4) [ + streamid(4) ] + buflen(4) */ channel->write_packet_len = buflen + (stream_id ? 13 : 9); - channel->write_packet = LIBSSH2_ALLOC(session, channel->write_packet_len); + channel->write_packet = + LIBSSH2_ALLOC(session, channel->write_packet_len); if (!channel->write_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocte space for data transmission packet", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocte space for data transmission packet", + 0); return -1; } @@ -1420,10 +1674,14 @@ LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int strea channel->write_bufwrite = buflen; channel->write_s = channel->write_packet; - *(channel->write_s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : SSH_MSG_CHANNEL_DATA; - libssh2_htonu32(channel->write_s, channel->remote.id); channel->write_s += 4; + *(channel->write_s++) = + stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : + SSH_MSG_CHANNEL_DATA; + libssh2_htonu32(channel->write_s, channel->remote.id); + channel->write_s += 4; if (stream_id) { - libssh2_htonu32(channel->write_s, stream_id); channel->write_s += 4; + libssh2_htonu32(channel->write_s, stream_id); + channel->write_s += 4; } /* twiddle our thumbs until there's window space available */ @@ -1453,31 +1711,41 @@ LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int strea /* Don't exceed the remote end's limits */ /* REMEMBER local means local as the SOURCE of the data */ if (channel->write_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); + _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); channel->write_bufwrite = channel->local.window_size; } if (channel->write_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); + _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); channel->write_bufwrite = channel->local.packet_size; } - libssh2_htonu32(channel->write_s, channel->write_bufwrite); channel->write_s += 4; - memcpy(channel->write_s, buf, channel->write_bufwrite); channel->write_s += channel->write_bufwrite; + libssh2_htonu32(channel->write_s, channel->write_bufwrite); + channel->write_s += 4; + memcpy(channel->write_s, buf, channel->write_bufwrite); + channel->write_s += channel->write_bufwrite; - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending %d bytes on channel %lu/%lu, stream_id=%d", - (int)channel->write_bufwrite, channel->local.id, channel->remote.id, stream_id); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Sending %d bytes on channel %lu/%lu, stream_id=%d", + (int) channel->write_bufwrite, channel->local.id, + channel->remote.id, stream_id); channel->write_state = libssh2_NB_state_created; } - + if (channel->write_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, channel->write_packet, channel->write_s - channel->write_packet); + rc = libssh2_packet_write(session, channel->write_packet, + channel->write_s - + channel->write_packet); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel data", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel data", 0); LIBSSH2_FREE(session, channel->write_packet); channel->write_packet = NULL; channel->write_state = libssh2_NB_state_idle; @@ -1495,9 +1763,9 @@ LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int strea /* * Not sure this is still wanted - if (!channel->session->socket_block) { - break; - } + if (!channel->session->socket_block) { + break; + } */ } } @@ -1509,45 +1777,51 @@ LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int strea return channel->write_bufwrote; } + /* }}} */ /* {{{ libssh2_channel_send_eof * Send EOF on channel */ -LIBSSH2_API int libssh2_channel_send_eof(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) */ + unsigned char packet[5]; /* packet_type(1) + channelno(4) */ int rc; - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Sending EOF on channel %lu/%lu", channel->local.id, channel->remote.id); + _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); rc = libssh2_packet_write(session, packet, 5); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send EOF on channel", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send EOF on channel", 0); return -1; } channel->local.eof = 1; return 0; } + /* }}} */ /* {{{ libssh2_channel_eof * Read channel's eof status */ -LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel) +LIBSSH2_API int +libssh2_channel_eof(LIBSSH2_CHANNEL * channel) { 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))) { + 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; } @@ -1556,22 +1830,26 @@ LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel) return channel->remote.eof; } + /* }}} */ /* {{{ libssh2_channel_wait_closed * Awaiting channel EOF */ -LIBSSH2_API int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel) +LIBSSH2_API int +libssh2_channel_wait_eof(LIBSSH2_CHANNEL * channel) { - LIBSSH2_SESSION* session = channel->session; + LIBSSH2_SESSION *session = channel->session; int rc; - + if (channel->wait_eof_state == libssh2_NB_state_idle) { - _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); + channel->wait_eof_state = libssh2_NB_state_created; } - + /* * While channel is not eof, read more packets from the network. * Either the EOF will be set or network timeout will occur. @@ -1583,24 +1861,25 @@ LIBSSH2_API int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel) rc = libssh2_packet_read(session); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc < 0) { + } else if (rc < 0) { channel->wait_eof_state = libssh2_NB_state_idle; return -1; } } while (1); - + channel->wait_eof_state = libssh2_NB_state_idle; - + return 0; } + /* }}} */ /* {{{ libssh2_channel_close * Close a channel */ -LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel) +LIBSSH2_API int +libssh2_channel_close(LIBSSH2_CHANNEL * channel) { LIBSSH2_SESSION *session = channel->session; int rc = 0; @@ -1614,7 +1893,8 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel) } if (channel->close_state == libssh2_NB_state_idle) { - _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); @@ -1631,9 +1911,9 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel) retcode = libssh2_packet_write(session, channel->close_packet, 5); if (retcode == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (retcode) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send close-channel request", 0); + } else if (retcode) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send close-channel request", 0); channel->close_state = libssh2_NB_state_idle; return -1; } @@ -1650,8 +1930,7 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel) ret = libssh2_packet_read(session); if (ret == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (ret < 0) { + } else if (ret < 0) { rc = -1; } } while ((ret != SSH_MSG_CHANNEL_CLOSE) && (rc == 0)); @@ -1662,23 +1941,29 @@ LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel) return rc; } + /* }}} */ /* {{{ libssh2_channel_wait_closed * Awaiting channel close after EOF */ -LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel) +LIBSSH2_API int +libssh2_channel_wait_closed(LIBSSH2_CHANNEL * channel) { - LIBSSH2_SESSION* session = channel->session; + LIBSSH2_SESSION *session = channel->session; int rc; if (!libssh2_channel_eof(channel)) { - libssh2_error(session, LIBSSH2_ERROR_INVAL, "libssh2_channel_wait_closed() invoked when channel is not in EOF state", 0); + libssh2_error(session, LIBSSH2_ERROR_INVAL, + "libssh2_channel_wait_closed() invoked when channel is not in EOF state", + 0); return -1; } if (channel->wait_closed_state == libssh2_NB_state_idle) { - _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); channel->wait_closed_state = libssh2_NB_state_created; } @@ -1694,8 +1979,7 @@ LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel) rc = libssh2_packet_read(session); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc <= 0) { + } else if (rc <= 0) { break; } } while (1); @@ -1704,6 +1988,7 @@ LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel) return 1; } + /* }}} */ @@ -1713,7 +1998,8 @@ LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel) * * Returns 0 on success, -1 on failure */ -LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel) +LIBSSH2_API int +libssh2_channel_free(LIBSSH2_CHANNEL * channel) { LIBSSH2_SESSION *session = channel->session; unsigned char channel_id[4]; @@ -1722,13 +2008,16 @@ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel) int rc; if (channel->free_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Freeing channel %lu/%lu resources", channel->local.id, channel->remote.id); - + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Freeing channel %lu/%lu resources", channel->local.id, + channel->remote.id); + channel->free_state = libssh2_NB_state_created; } - + /* Allow channel freeing even when the socket has lost its connection */ - if (!channel->local.close && (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) { + if (!channel->local.close + && (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) { while ((rc = libssh2_channel_close(channel)) == PACKET_EAGAIN); if (rc) { channel->free_state = libssh2_NB_state_idle; @@ -1746,8 +2035,13 @@ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel) /* 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)) { + 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); } @@ -1786,11 +2080,12 @@ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel) if (channel->write_packet) { LIBSSH2_FREE(session, channel->write_packet); } - + LIBSSH2_FREE(session, channel); return 0; } + /* }}} */ /* {{{ libssh2_channel_window_read_ex @@ -1799,7 +2094,10 @@ LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel) * read_avail (if passed) will be populated with the number of bytes actually available to be read * window_size_initial (if passed) will be populated with the window_size_initial as defined by the channel_open request */ -LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, unsigned long *read_avail, unsigned long *window_size_initial) +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; @@ -1812,8 +2110,9 @@ LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channe 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)) { + 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; } @@ -1825,6 +2124,7 @@ LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channe return channel->remote.window_size; } + /* }}} */ /* {{{ libssh2_channel_window_write_ex @@ -1832,7 +2132,9 @@ LIBSSH2_API unsigned long libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channe * Returns the number of bytes which may be safely writen on the channel without blocking * window_size_initial (if passed) will be populated with the size of the initial window as defined by the channel_open request */ -LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, unsigned long *window_size_initial) +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 */ @@ -1841,4 +2143,5 @@ LIBSSH2_API unsigned long libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *chann return channel->local.window_size; } + /* }}} */ diff --git a/src/comp.c b/src/comp.c index 558ddf7..e8c83c8 100644 --- a/src/comp.c +++ b/src/comp.c @@ -47,27 +47,28 @@ /* {{{ libssh2_comp_method_none_comp * 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) +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) { - (void)session; - (void)compress; - (void)payload_limit; - (void)abstract; - *dest = (unsigned char *)src; + (void) session; + (void) compress; + (void) payload_limit; + (void) abstract; + *dest = (unsigned char *) src; *dest_len = src_len; *free_dest = 0; return 0; } + /* }}} */ static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = { @@ -87,39 +88,46 @@ static const LIBSSH2_COMP_METHOD libssh2_comp_method_none = { * Deal... */ -static voidpf libssh2_comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size) +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) +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_comp_method_zlib_init * All your bandwidth are belong to us (so save some) */ -static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress, void **abstract) +static int +libssh2_comp_method_zlib_init(LIBSSH2_SESSION * session, int compress, + void **abstract) { 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); + 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; + 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); @@ -136,20 +144,21 @@ static int libssh2_comp_method_zlib_init(LIBSSH2_SESSION *session, int compress, return 0; } + /* }}} */ /* {{{ libssh2_comp_method_zlib_comp * 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) +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) { z_stream *strm = *abstract; /* A short-term alloc of a full data chunk is better than a series of @@ -163,17 +172,19 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session, out_maxlen = 25; } - if (out_maxlen > (int)payload_limit) { + if (out_maxlen > (int) payload_limit) { out_maxlen = payload_limit; } - strm->next_in = (unsigned char *)src; + 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->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); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate compression/decompression buffer", + 0); return -1; } while (strm->avail_in) { @@ -185,7 +196,8 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session, status = inflate(strm, Z_PARTIAL_FLUSH); } if (status != Z_OK) { - libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0); + libssh2_error(session, LIBSSH2_ERROR_ZLIB, + "compress/decompression failure", 0); LIBSSH2_FREE(session, out); return -1; } @@ -193,80 +205,92 @@ static int libssh2_comp_method_zlib_comp(LIBSSH2_SESSION *session, 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++) { + if ((out_maxlen > (int) payload_limit) && !compress && limiter++) { libssh2_error(session, LIBSSH2_ERROR_ZLIB, - "Excessive growth in decompression phase", 0); + "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_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; + 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 (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 (status != Z_OK) { - libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compress/decompression failure", 0); - LIBSSH2_FREE(session, out); - return -1; - } - } } - *dest = (unsigned char *)out; + *dest = (unsigned char *) out; *dest_len = out_maxlen - strm->avail_out; *free_dest = 1; return 0; } + /* }}} */ /* {{{ libssh2_comp_method_zlib_dtor * All done, no more compression for you */ -static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress, void **abstract) +static int +libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION * session, int compress, + void **abstract) { z_stream *strm = *abstract; @@ -286,6 +310,7 @@ static int libssh2_comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compress, return 0; } + /* }}} */ static const LIBSSH2_COMP_METHOD libssh2_comp_method_zlib = { @@ -308,7 +333,8 @@ static const LIBSSH2_COMP_METHOD *_libssh2_comp_methods[] = { NULL }; -const LIBSSH2_COMP_METHOD **libssh2_comp_methods(void) { +const LIBSSH2_COMP_METHOD ** +libssh2_comp_methods(void) +{ return _libssh2_comp_methods; } - diff --git a/src/crypt.c b/src/crypt.c index 9ab1cab..2f32877 100644 --- a/src/crypt.c +++ b/src/crypt.c @@ -41,47 +41,51 @@ /* {{{ libssh2_crypt_none_crypt * Minimalist cipher: VERY secure *wink* */ -static int libssh2_crypt_none_crypt(LIBSSH2_SESSION *session, unsigned char *buf, void **abstract) +static int +libssh2_crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf, + void **abstract) { /* 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 */ + 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 { +struct crypt_ctx +{ int encrypt; - _libssh2_cipher_type(algo); + _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) +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) { struct crypt_ctx *ctx = LIBSSH2_ALLOC(session, - sizeof(struct crypt_ctx)); + 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); + if (_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) { + LIBSSH2_FREE(session, ctx); return -1; } *abstract = ctx; @@ -90,17 +94,19 @@ static int _libssh2_init (LIBSSH2_SESSION *session, return 0; } -static int _libssh2_encrypt(LIBSSH2_SESSION *session, unsigned char *block, void **abstract) +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) +static int +_libssh2_dtor(LIBSSH2_SESSION * session, void **abstract) { - struct crypt_ctx **cctx = (struct crypt_ctx **)abstract; + struct crypt_ctx **cctx = (struct crypt_ctx **) abstract; if (cctx && *cctx) { _libssh2_cipher_dtor(&(*cctx)->h); LIBSSH2_FREE(session, *cctx); @@ -112,10 +118,10 @@ static int _libssh2_dtor(LIBSSH2_SESSION *session, void **abstract) #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 */ + 16, /* blocksize */ + 16, /* initial value length */ + 16, /* secret length -- 16*8 == 128bit */ + 0, /* flags */ &_libssh2_init, &_libssh2_encrypt, &_libssh2_dtor, @@ -124,10 +130,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = { 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 */ + 16, /* blocksize */ + 16, /* initial value length */ + 24, /* secret length -- 24*8 == 192bit */ + 0, /* flags */ &_libssh2_init, &_libssh2_encrypt, &_libssh2_dtor, @@ -136,10 +142,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = { 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 */ + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ &_libssh2_init, &_libssh2_encrypt, &_libssh2_dtor, @@ -147,12 +153,13 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = { }; /* rijndael-cbc@lysator.liu.se == aes256-cbc */ -static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_rijndael_cbc_lysator_liu_se = { +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 */ + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ &_libssh2_init, &_libssh2_encrypt, &_libssh2_dtor, @@ -163,10 +170,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_rijndael_cbc_lysator_liu_ #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 */ + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ &_libssh2_init, &_libssh2_encrypt, &_libssh2_dtor, @@ -177,10 +184,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = { #if LIBSSH2_RC4 static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = { "arcfour", - 8, /* blocksize */ - 8, /* initial value length */ - 16, /* secret length */ - 0, /* flags */ + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ &_libssh2_init, &_libssh2_encrypt, &_libssh2_dtor, @@ -191,10 +198,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = { #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 */ + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ &_libssh2_init, &_libssh2_encrypt, &_libssh2_dtor, @@ -205,10 +212,10 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = { #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 */ + 8, /* blocksize */ + 8, /* initial value length */ + 24, /* secret length */ + 0, /* flags */ &_libssh2_init, &_libssh2_encrypt, &_libssh2_dtor, @@ -219,7 +226,7 @@ static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = { 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_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */ &libssh2_crypt_method_aes192_cbc, &libssh2_crypt_method_aes128_cbc, #endif /* LIBSSH2_AES */ @@ -242,6 +249,8 @@ static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = { }; /* Expose to kex.c */ -const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void) { +const LIBSSH2_CRYPT_METHOD ** +libssh2_crypt_methods(void) +{ return _libssh2_crypt_methods; } diff --git a/src/hostkey.c b/src/hostkey.c index d1dbbd6..b25fd31 100644 --- a/src/hostkey.c +++ b/src/hostkey.c @@ -47,22 +47,23 @@ * ssh-rsa * *********** */ -static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, void **abstract); +static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, + void **abstract); /* {{{ libssh2_hostkey_method_ssh_rsa_init * Initialize the server hostkey working area with e/n pair */ static int -libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session, - const unsigned char *hostkey_data, - unsigned long hostkey_data_len, - void **abstract) +libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session, + 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; - (void)hostkey_data_len; + (void) hostkey_data_len; if (*abstract) { libssh2_hostkey_method_ssh_rsa_dtor(session, abstract); @@ -73,7 +74,7 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session, len = libssh2_ntohu32(s); s += 4; - if (len != 7 || strncmp((char *)s, "ssh-rsa", 7) != 0) { + if (len != 7 || strncmp((char *) s, "ssh-rsa", 7) != 0) { return -1; } s += 7; @@ -81,25 +82,32 @@ libssh2_hostkey_method_ssh_rsa_init(LIBSSH2_SESSION *session, 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; return 0; } + /* }}} */ /* {{{ libssh2_hostkey_method_ssh_rsa_initPEM * 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) +static int +libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session, + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) { libssh2_rsa_ctx *rsactx; FILE *fp; @@ -115,7 +123,7 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session, return -1; } - ret = _libssh2_rsa_new_private (&rsactx, session, fp, passphrase); + ret = _libssh2_rsa_new_private(&rsactx, session, fp, passphrase); fclose(fp); if (ret) { return -1; @@ -125,34 +133,42 @@ static int libssh2_hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION *session, return 0; } + /* }}} */ /* {{{ libssh2_hostkey_method_ssh_rsa_sign * 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) +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) { - 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); + sig += 15; + sig_len -= 15; + return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len); } + /* }}} */ /* {{{ libssh2_hostkey_method_ssh_rsa_signv * 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) +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) { - libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx*)(*abstract); + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); int ret; unsigned int i; unsigned char hash[SHA_DIGEST_LENGTH]; @@ -165,23 +181,24 @@ static int libssh2_hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION *session, unsign libssh2_sha1_final(ctx, hash); ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, - signature, signature_len); + signature, signature_len); if (ret) { return -1; } return 0; } + /* }}} */ /* {{{ libssh2_hostkey_method_ssh_rsa_dtor * Shutdown the hostkey */ -static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, - void **abstract) +static int +libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, 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); @@ -189,6 +206,7 @@ static int libssh2_hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION *session, return 0; } + /* }}} */ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = { @@ -198,7 +216,7 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = { libssh2_hostkey_method_ssh_rsa_initPEM, libssh2_hostkey_method_ssh_rsa_sig_verify, libssh2_hostkey_method_ssh_rsa_signv, - NULL, /* encrypt */ + NULL, /* encrypt */ libssh2_hostkey_method_ssh_rsa_dtor, }; #endif /* LIBSSH2_RSA */ @@ -208,21 +226,22 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_rsa = { * ssh-dss * *********** */ -static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, void **abstract); +static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, + void **abstract); /* {{{ libssh2_hostkey_method_ssh_dss_init * Initialize the server hostkey working area with p/q/g/y set */ static int -libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session, - const unsigned char *hostkey_data, - unsigned long hostkey_data_len, - void **abstract) +libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session, + 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; + (void) hostkey_data_len; if (*abstract) { libssh2_hostkey_method_ssh_dss_dtor(session, abstract); @@ -230,36 +249,47 @@ libssh2_hostkey_method_ssh_dss_init(LIBSSH2_SESSION *session, } s = hostkey_data; - len = libssh2_ntohu32(s); s += 4; - if (len != 7 || strncmp((char *)s, "ssh-dss", 7) != 0) { + len = libssh2_ntohu32(s); + s += 4; + if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) { return -1; - } s += 7; + } + 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; return 0; } + /* }}} */ /* {{{ libssh2_hostkey_method_ssh_dss_initPEM * 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) +static int +libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session, + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) { libssh2_dsa_ctx *dsactx; FILE *fp; @@ -275,7 +305,7 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session, return -1; } - ret = _libssh2_dsa_new_private (&dsactx, session, fp, passphrase); + ret = _libssh2_dsa_new_private(&dsactx, session, fp, passphrase); fclose(fp); if (ret) { return -1; @@ -285,33 +315,46 @@ static int libssh2_hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION *session, return 0; } + /* }}} */ /* {{{ libssh2_hostkey_method_ssh_dss_sign * 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) +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) { - 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; + sig += 15; + sig_len -= 15; if (sig_len != 40) { - libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid DSS signature length", 0); + libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Invalid DSS signature length", 0); return -1; } return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len); } + /* }}} */ /* {{{ libssh2_hostkey_method_ssh_dss_signv * 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) +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) { - libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx*)(*abstract); + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); unsigned char hash[SHA_DIGEST_LENGTH]; libssh2_sha1_ctx ctx; unsigned int i; @@ -330,25 +373,24 @@ static int libssh2_hostkey_method_ssh_dss_signv(LIBSSH2_SESSION *session, unsign } libssh2_sha1_final(ctx, hash); - if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, - *signature)) - { + if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) { LIBSSH2_FREE(session, *signature); return -1; } return 0; } + /* }}} */ /* {{{ libssh2_hostkey_method_ssh_dss_dtor * Shutdown the hostkey method */ -static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, - void **abstract) +static int +libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, 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); @@ -356,6 +398,7 @@ static int libssh2_hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION *session, return 0; } + /* }}} */ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = { @@ -365,7 +408,7 @@ static const LIBSSH2_HOSTKEY_METHOD libssh2_hostkey_method_ssh_dss = { libssh2_hostkey_method_ssh_dss_initPEM, libssh2_hostkey_method_ssh_dss_sig_verify, libssh2_hostkey_method_ssh_dss_signv, - NULL, /* encrypt */ + NULL, /* encrypt */ libssh2_hostkey_method_ssh_dss_dtor, }; #endif /* LIBSSH2_DSA */ @@ -380,7 +423,8 @@ static const LIBSSH2_HOSTKEY_METHOD *_libssh2_hostkey_methods[] = { NULL }; -const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void) +const LIBSSH2_HOSTKEY_METHOD ** +libssh2_hostkey_methods(void) { return _libssh2_hostkey_methods; } @@ -391,21 +435,21 @@ const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void) * Length of buffer is determined by hash type * i.e. MD5 == 16, SHA1 == 20 */ -LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, int hash_type) +LIBSSH2_API const char * +libssh2_hostkey_hash(LIBSSH2_SESSION * session, int 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 75f758d..9ae59c5 100644 --- a/src/kex.c +++ b/src/kex.c @@ -68,11 +68,22 @@ /* {{{ 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, kmdhgGPsha1kex_state_t *exchange_state) +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, + kmdhgGPsha1kex_state_t + * exchange_state) { int ret = 0; int rc; @@ -87,113 +98,132 @@ libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *ses exchange_state->e = _libssh2_bn_init(); /* g^x mod p */ exchange_state->f = _libssh2_bn_init(); /* g^(Random from server) mod p */ exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod p */ - + /* Zero the whole thing out */ memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t)); - + /* Generate x and e */ _libssh2_bn_rand(exchange_state->x, group_order, 0, -1); - _libssh2_bn_mod_exp(exchange_state->e, g, exchange_state->x, p, exchange_state->ctx); - + _libssh2_bn_mod_exp(exchange_state->e, g, exchange_state->x, p, + exchange_state->ctx); + /* Send KEX init */ /* packet_type(1) + String Length(4) + leading 0(1) */ - exchange_state->e_packet_len = _libssh2_bn_bytes(exchange_state->e) + 6; + exchange_state->e_packet_len = + _libssh2_bn_bytes(exchange_state->e) + 6; if (_libssh2_bn_bits(exchange_state->e) % 8) { /* Leading 00 not needed */ exchange_state->e_packet_len--; } - - exchange_state->e_packet = LIBSSH2_ALLOC(session, exchange_state->e_packet_len); + + exchange_state->e_packet = + LIBSSH2_ALLOC(session, exchange_state->e_packet_len); if (!exchange_state->e_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory error", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Out of memory error", + 0); ret = -1; goto clean_exit; } exchange_state->e_packet[0] = packet_type_init; - libssh2_htonu32(exchange_state->e_packet + 1, exchange_state->e_packet_len - 5); + libssh2_htonu32(exchange_state->e_packet + 1, + exchange_state->e_packet_len - 5); if (_libssh2_bn_bits(exchange_state->e) % 8) { - _libssh2_bn_to_bin(exchange_state->e, exchange_state->e_packet + 5); + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 5); } else { exchange_state->e_packet[5] = 0; - _libssh2_bn_to_bin(exchange_state->e, exchange_state->e_packet + 6); + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 6); } - - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending KEX packet %d", - (int)packet_type_init); + + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Sending KEX packet %d", + (int) packet_type_init); exchange_state->state = libssh2_NB_state_created; } - + if (exchange_state->state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, exchange_state->e_packet, exchange_state->e_packet_len); + rc = libssh2_packet_write(session, exchange_state->e_packet, + exchange_state->e_packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send KEX init message", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send KEX init message", 0); ret = -1; goto clean_exit; } exchange_state->state = libssh2_NB_state_sent; } - + if (exchange_state->state == libssh2_NB_state_sent) { 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, &exchange_state->burn_state); + + _libssh2_debug(session, LIBSSH2_DBG_KEX, + "Waiting for badly guessed KEX packet (to be ignored)"); + burn_type = + libssh2_packet_burn(session, &exchange_state->burn_state); if (burn_type == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (burn_type <= 0) { + } else 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); } - + exchange_state->state = libssh2_NB_state_sent1; } - + if (exchange_state->state == libssh2_NB_state_sent1) { /* Wait for KEX reply */ - rc = libssh2_packet_require_ex(session, packet_type_reply, &exchange_state->s_packet, &exchange_state->s_packet_len, - 0, NULL, 0, &exchange_state->req_state); + rc = libssh2_packet_require_ex(session, packet_type_reply, + &exchange_state->s_packet, + &exchange_state->s_packet_len, 0, NULL, + 0, &exchange_state->req_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; } if (rc) { - libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timed out waiting for KEX reply", 0); + libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting for KEX reply", 0); ret = -1; goto clean_exit; } - + /* Parse KEXDH_REPLY */ exchange_state->s = exchange_state->s_packet + 1; - + session->server_hostkey_len = libssh2_ntohu32(exchange_state->s); exchange_state->s += 4; - session->server_hostkey = LIBSSH2_ALLOC(session, session->server_hostkey_len); + 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); + 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, exchange_state->s, session->server_hostkey_len); + memcpy(session->server_hostkey, exchange_state->s, + session->server_hostkey_len); exchange_state->s += session->server_hostkey_len; - + #if LIBSSH2_MD5 { libssh2_md5_ctx fingerprint_ctx; - + libssh2_md5_init(&fingerprint_ctx); - libssh2_md5_update(fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5); } #ifdef LIBSSH2DEBUG @@ -204,137 +234,186 @@ libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *ses snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); } *(--fprint) = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_KEX, + _libssh2_debug(session, LIBSSH2_DBG_KEX, "Server's MD5 Fingerprint: %s", fingerprint); } #endif /* LIBSSH2DEBUG */ #endif /* ! LIBSSH2_MD5 */ - + { libssh2_sha1_ctx fingerprint_ctx; - + libssh2_sha1_init(&fingerprint_ctx); - libssh2_sha1_update (fingerprint_ctx, session->server_hostkey, session->server_hostkey_len); + 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); + _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); + + 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; } - + exchange_state->f_value_len = libssh2_ntohu32(exchange_state->s); exchange_state->s += 4; exchange_state->f_value = exchange_state->s; exchange_state->s += exchange_state->f_value_len; - _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len, exchange_state->f_value); - + _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len, + exchange_state->f_value); + exchange_state->h_sig_len = libssh2_ntohu32(exchange_state->s); exchange_state->s += 4; exchange_state->h_sig = exchange_state->s; - + /* Compute the shared secret */ - _libssh2_bn_mod_exp(exchange_state->k, exchange_state->f, exchange_state->x, p, exchange_state->ctx); + _libssh2_bn_mod_exp(exchange_state->k, exchange_state->f, + exchange_state->x, p, exchange_state->ctx); exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; if (_libssh2_bn_bits(exchange_state->k) % 8) { /* don't need leading 00 */ exchange_state->k_value_len--; } - exchange_state->k_value = LIBSSH2_ALLOC(session, exchange_state->k_value_len); + exchange_state->k_value = + LIBSSH2_ALLOC(session, exchange_state->k_value_len); if (!exchange_state->k_value) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate buffer for K", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for K", 0); ret = -1; goto clean_exit; } - libssh2_htonu32(exchange_state->k_value, exchange_state->k_value_len - 4); + libssh2_htonu32(exchange_state->k_value, + exchange_state->k_value_len - 4); if (_libssh2_bn_bits(exchange_state->k) % 8) { _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); } else { exchange_state->k_value[4] = 0; _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); } - + libssh2_sha1_init(&exchange_state->exchange_hash); if (session->local.banner) { - libssh2_htonu32(exchange_state->h_sig_comp, strlen((char *)session->local.banner) - 2); - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->h_sig_comp, 4); - libssh2_sha1_update(exchange_state->exchange_hash, (char *)session->local.banner, - strlen((char *)session->local.banner) - 2); + libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->local.banner) - 2); + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_state->exchange_hash, + (char *) session->local.banner, + strlen((char *) session->local.banner) - 2); } else { - libssh2_htonu32(exchange_state->h_sig_comp, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->h_sig_comp, 4); - libssh2_sha1_update(exchange_state->exchange_hash, LIBSSH2_SSH_DEFAULT_BANNER, + libssh2_htonu32(exchange_state->h_sig_comp, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_state->exchange_hash, + LIBSSH2_SSH_DEFAULT_BANNER, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); } - - libssh2_htonu32(exchange_state->h_sig_comp, strlen((char *)session->remote.banner)); - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->h_sig_comp, 4); - libssh2_sha1_update(exchange_state->exchange_hash, session->remote.banner, - strlen((char *)session->remote.banner)); - - libssh2_htonu32(exchange_state->h_sig_comp, session->local.kexinit_len); - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->h_sig_comp, 4); - libssh2_sha1_update(exchange_state->exchange_hash, session->local.kexinit, session->local.kexinit_len); - - libssh2_htonu32(exchange_state->h_sig_comp, session->remote.kexinit_len); - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->h_sig_comp, 4); - libssh2_sha1_update(exchange_state->exchange_hash, session->remote.kexinit, session->remote.kexinit_len); - - libssh2_htonu32(exchange_state->h_sig_comp, session->server_hostkey_len); - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->h_sig_comp, 4); - libssh2_sha1_update(exchange_state->exchange_hash, session->server_hostkey, session->server_hostkey_len); - + + libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->remote.banner)); + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_state->exchange_hash, + session->remote.banner, + strlen((char *) session->remote.banner)); + + libssh2_htonu32(exchange_state->h_sig_comp, + session->local.kexinit_len); + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_state->exchange_hash, + session->local.kexinit, + session->local.kexinit_len); + + libssh2_htonu32(exchange_state->h_sig_comp, + session->remote.kexinit_len); + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_state->exchange_hash, + session->remote.kexinit, + session->remote.kexinit_len); + + libssh2_htonu32(exchange_state->h_sig_comp, + session->server_hostkey_len); + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_state->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 */ #ifdef LIBSSH2_DH_GEX_NEW - libssh2_htonu32(exchange_state->h_sig_comp, LIBSSH2_DH_GEX_MINGROUP); - libssh2_htonu32(exchange_state->h_sig_comp+4, LIBSSH2_DH_GEX_OPTGROUP); - libssh2_htonu32(exchange_state->h_sig_comp+8, LIBSSH2_DH_GEX_MAXGROUP); - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->h_sig_comp, 12); + libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_MINGROUP); + libssh2_htonu32(exchange_state->h_sig_comp + 4, + LIBSSH2_DH_GEX_OPTGROUP); + libssh2_htonu32(exchange_state->h_sig_comp + 8, + LIBSSH2_DH_GEX_MAXGROUP); + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->h_sig_comp, 12); #else - libssh2_htonu32(exchange_state->h_sig_comp, LIBSSH2_DH_GEX_OPTGROUP); - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->h_sig_comp, 4); + libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_OPTGROUP); + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->h_sig_comp, 4); #endif } - + if (midhash) { - libssh2_sha1_update(exchange_state->exchange_hash, midhash, midhash_len); + libssh2_sha1_update(exchange_state->exchange_hash, midhash, + midhash_len); } - - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->e_packet + 1, exchange_state->e_packet_len - 1); - - libssh2_htonu32(exchange_state->h_sig_comp, exchange_state->f_value_len); - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->h_sig_comp, 4); - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->f_value, exchange_state->f_value_len); - - libssh2_sha1_update(exchange_state->exchange_hash, exchange_state->k_value, exchange_state->k_value_len); - - libssh2_sha1_final(exchange_state->exchange_hash, exchange_state->h_sig_comp); - - if (session->hostkey->sig_verify(session, exchange_state->h_sig, exchange_state->h_sig_len, - exchange_state->h_sig_comp, 20, &session->server_hostkey_abstract)) { - libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, "Unable to verify hostkey signature", 0); + + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->e_packet + 1, + exchange_state->e_packet_len - 1); + + libssh2_htonu32(exchange_state->h_sig_comp, + exchange_state->f_value_len); + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->f_value, + exchange_state->f_value_len); + + libssh2_sha1_update(exchange_state->exchange_hash, + exchange_state->k_value, + exchange_state->k_value_len); + + libssh2_sha1_final(exchange_state->exchange_hash, + exchange_state->h_sig_comp); + + if (session->hostkey-> + sig_verify(session, exchange_state->h_sig, + exchange_state->h_sig_len, exchange_state->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"); exchange_state->c = SSH_MSG_NEWKEYS; - + exchange_state->state = libssh2_NB_state_sent2; } @@ -342,25 +421,26 @@ libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *ses rc = libssh2_packet_write(session, &exchange_state->c, 1); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send NEWKEYS message", 0); ret = -1; goto clean_exit; } - + exchange_state->state = libssh2_NB_state_sent3; } - + if (exchange_state->state == libssh2_NB_state_sent3) { - rc = libssh2_packet_require_ex(session, SSH_MSG_NEWKEYS, &exchange_state->tmp, &exchange_state->tmp_len, 0, NULL, 0, + rc = libssh2_packet_require_ex(session, SSH_MSG_NEWKEYS, + &exchange_state->tmp, + &exchange_state->tmp_len, 0, NULL, 0, &exchange_state->req_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timed out waiting for NEWKEYS", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting for NEWKEYS", 0); ret = -1; goto clean_exit; } @@ -368,149 +448,172 @@ libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION *ses 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, exchange_state->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, exchange_state->h_sig_comp, SHA_DIGEST_LENGTH); + memcpy(session->session_id, exchange_state->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); + 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"); + + 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"); + 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)) { + 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); } } - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Client to Server IV and Key calculated"); - + _libssh2_debug(session, LIBSSH2_DBG_KEX, + "Client to Server IV and Key calculated"); + if (session->remote.crypt->dtor) { /* Cleanup any existing cipher */ - session->remote.crypt->dtor(session, &session->remote.crypt_abstract); + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); } - + 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(iv, session->remote.crypt->iv_len, "B"); + + 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"); + 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)) { + 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_iv) { memset(iv, 0, session->remote.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"); - + _libssh2_debug(session, LIBSSH2_DBG_KEX, + "Server to Client IV and Key calculated"); + if (session->local.mac->dtor) { session->local.mac->dtor(session, &session->local.mac_abstract); } - + if (session->local.mac->init) { unsigned char *key = NULL; int free_key = 0; - - LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, session->local.mac->key_len, "E"); + + 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); - + 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"); - + _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"); + + 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); - + 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"); + _libssh2_debug(session, LIBSSH2_DBG_KEX, + "Server to Client HMAC Key calculated"); } - -clean_exit: + + clean_exit: _libssh2_bn_free(exchange_state->x); exchange_state->x = NULL; _libssh2_bn_free(exchange_state->e); @@ -521,38 +624,42 @@ clean_exit: exchange_state->k = NULL; _libssh2_bn_ctx_free(exchange_state->ctx); exchange_state->ctx = NULL; - + if (exchange_state->e_packet) { LIBSSH2_FREE(session, exchange_state->e_packet); exchange_state->e_packet = NULL; } - + if (exchange_state->s_packet) { LIBSSH2_FREE(session, exchange_state->s_packet); exchange_state->s_packet = NULL; } - + if (exchange_state->k_value) { LIBSSH2_FREE(session, exchange_state->k_value); exchange_state->k_value = NULL; } - + if (session->server_hostkey) { LIBSSH2_FREE(session, session->server_hostkey); session->server_hostkey = NULL; } - + exchange_state->state = libssh2_NB_state_idle; return ret; } + /* }}} */ /* {{{ libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange * Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1 */ -static int -libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session, key_exchange_state_low_t *key_state) +static int +libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION * + session, + key_exchange_state_low_t + * key_state) { static const unsigned char p_value[128] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -570,26 +677,37 @@ libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *sess 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 }; - + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + int ret; - + if (key_state->state == libssh2_NB_state_idle) { /* g == 2 */ - key_state->p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */ - key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ + key_state->p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */ + key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ /* Initialize P and G */ _libssh2_bn_set_word(key_state->g, 2); _libssh2_bn_from_bin(key_state->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"); + key_state->state = libssh2_NB_state_created; } - ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, key_state->g, key_state->p, 128, SSH_MSG_KEXDH_INIT, - SSH_MSG_KEXDH_REPLY, NULL, 0, &key_state->exchange_state); + ret = + libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, + key_state-> + g, + key_state-> + p, 128, + SSH_MSG_KEXDH_INIT, + SSH_MSG_KEXDH_REPLY, + NULL, 0, + &key_state-> + exchange_state); if (ret == PACKET_EAGAIN) { return PACKET_EAGAIN; } @@ -602,13 +720,17 @@ libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *sess return ret; } + /* }}} */ /* {{{ libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange * Diffie-Hellman Group14 Key Exchange using SHA1 */ static int -libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session, key_exchange_state_low_t *key_state) +libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION * + session, + key_exchange_state_low_t + * key_state) { static const unsigned char p_value[256] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -642,24 +764,35 @@ libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *ses 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 }; + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; int ret; - + if (key_state->state == libssh2_NB_state_idle) { - key_state->p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */ - key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ + key_state->p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */ + key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ /* g == 2 */ /* Initialize P and G */ _libssh2_bn_set_word(key_state->g, 2); _libssh2_bn_from_bin(key_state->p, 256, p_value); - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group14 Key Exchange"); - + _libssh2_debug(session, LIBSSH2_DBG_KEX, + "Initiating Diffie-Hellman Group14 Key Exchange"); + key_state->state = libssh2_NB_state_created; } - ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, key_state->g, key_state->p, 256, SSH_MSG_KEXDH_INIT, - SSH_MSG_KEXDH_REPLY, NULL, 0, &key_state->exchange_state); + ret = + libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, + key_state-> + g, + key_state-> + p, 256, + SSH_MSG_KEXDH_INIT, + SSH_MSG_KEXDH_REPLY, + NULL, 0, + &key_state-> + exchange_state); if (ret == PACKET_EAGAIN) { return PACKET_EAGAIN; } @@ -672,6 +805,7 @@ libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *ses return ret; } + /* }}} */ /* {{{ libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange @@ -679,7 +813,8 @@ libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *ses * Negotiates random(ish) group for secret derivation */ static int -libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange(LIBSSH2_SESSION *session, key_exchange_state_low_t *key_state) + libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange + (LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) { unsigned char *s; unsigned long p_len, g_len; @@ -687,67 +822,77 @@ libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange(LIBSSH2_SESSI int rc; if (key_state->state == libssh2_NB_state_idle) { - key_state->p = _libssh2_bn_init (); - key_state->g = _libssh2_bn_init (); - /* Ask for a P and G pair */ + key_state->p = _libssh2_bn_init(); + key_state->g = _libssh2_bn_init(); + /* Ask for a P and G pair */ #ifdef LIBSSH2_DH_GEX_NEW key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP); libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP); libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP); key_state->request_len = 13; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group-Exchange (New Method)"); + _libssh2_debug(session, LIBSSH2_DBG_KEX, + "Initiating Diffie-Hellman Group-Exchange (New Method)"); #else key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD; libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP); key_state->request_len = 5; - _libssh2_debug(session, LIBSSH2_DBG_KEX, "Initiating Diffie-Hellman Group-Exchange (Old Method)"); + _libssh2_debug(session, LIBSSH2_DBG_KEX, + "Initiating Diffie-Hellman Group-Exchange (Old Method)"); #endif - + key_state->state = libssh2_NB_state_created; } if (key_state->state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, key_state->request, key_state->request_len); + rc = libssh2_packet_write(session, key_state->request, + key_state->request_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send Group Exchange Request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send Group Exchange Request", 0); ret = -1; goto dh_gex_clean_exit; } - + key_state->state = libssh2_NB_state_sent; } if (key_state->state == libssh2_NB_state_sent) { - rc = libssh2_packet_require_ex(session, SSH_MSG_KEX_DH_GEX_GROUP, &key_state->data, &key_state->data_len, 0, NULL, 0, - &key_state->req_state); + rc = libssh2_packet_require_ex(session, SSH_MSG_KEX_DH_GEX_GROUP, + &key_state->data, &key_state->data_len, + 0, NULL, 0, &key_state->req_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, "Timeout waiting for GEX_GROUP reply", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timeout waiting for GEX_GROUP reply", 0); ret = -1; goto dh_gex_clean_exit; } - + key_state->state = libssh2_NB_state_sent1; } if (key_state->state == libssh2_NB_state_sent1) { s = key_state->data + 1; - p_len = libssh2_ntohu32(s); s += 4; - _libssh2_bn_from_bin(key_state->p, p_len, s); s += p_len; + p_len = libssh2_ntohu32(s); + s += 4; + _libssh2_bn_from_bin(key_state->p, p_len, s); + s += p_len; - g_len = libssh2_ntohu32(s); s += 4; - _libssh2_bn_from_bin(key_state->g, g_len, s); s += g_len; + g_len = libssh2_ntohu32(s); + s += 4; + _libssh2_bn_from_bin(key_state->g, g_len, s); + s += g_len; - ret = libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session, key_state->g, key_state->p, p_len, - SSH_MSG_KEX_DH_GEX_INIT, SSH_MSG_KEX_DH_GEX_REPLY, - key_state->data + 1, key_state->data_len - 1, - &key_state->exchange_state); + ret = + libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange + (session, key_state->g, key_state->p, p_len, + SSH_MSG_KEX_DH_GEX_INIT, SSH_MSG_KEX_DH_GEX_REPLY, + key_state->data + 1, key_state->data_len - 1, + &key_state->exchange_state); if (ret == PACKET_EAGAIN) { return PACKET_EAGAIN; } @@ -755,7 +900,7 @@ libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange(LIBSSH2_SESSI LIBSSH2_FREE(session, key_state->data); } - dh_gex_clean_exit: + dh_gex_clean_exit: key_state->state = libssh2_NB_state_idle; _libssh2_bn_free(key_state->g); key_state->g = NULL; @@ -764,6 +909,7 @@ libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange(LIBSSH2_SESSI return ret; } + /* }}} */ #define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001 @@ -781,7 +927,8 @@ static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group14_sha1 = LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, }; -static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group_exchange_sha1 = { +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, @@ -794,7 +941,8 @@ static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = { NULL }; -typedef struct _LIBSSH2_COMMON_METHOD { +typedef struct _LIBSSH2_COMMON_METHOD +{ const char *name; } LIBSSH2_COMMON_METHOD; @@ -803,7 +951,8 @@ typedef struct _LIBSSH2_COMMON_METHOD { * Includes SUM(strlen() of each individual method plus 1 (for coma)) - 1 (because the last coma isn't used) * Another sign of bad coding practices gone mad. Pretend you don't see this. */ -static size_t libssh2_kex_method_strlen(LIBSSH2_COMMON_METHOD **method) +static size_t +libssh2_kex_method_strlen(LIBSSH2_COMMON_METHOD ** method) { size_t len = 0; @@ -818,12 +967,15 @@ static size_t libssh2_kex_method_strlen(LIBSSH2_COMMON_METHOD **method) return len - 1; } + /* }}} */ /* {{{ libssh2_kex_method_list * Generate formatted preference list in buf */ -static size_t libssh2_kex_method_list(unsigned char *buf, size_t list_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; @@ -842,6 +994,7 @@ static size_t libssh2_kex_method_list(unsigned char *buf, size_t list_strlen, LI return list_strlen + 4; } + /* }}} */ #define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) ((prefvar) ? strlen(prefvar) : libssh2_kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar))) @@ -858,78 +1011,107 @@ static size_t libssh2_kex_method_list(unsigned char *buf, size_t list_strlen, LI /* {{{ libssh2_kexinit * Send SSH_MSG_KEXINIT packet */ -static int libssh2_kexinit(LIBSSH2_SESSION *session) +static int +libssh2_kexinit(LIBSSH2_SESSION * session) { /* 62 = packet_type(1) + cookie(16) + first_packet_follows(1) + - reserved(4) + length longs(40) */ + reserved(4) + length longs(40) */ size_t data_len = 62; - 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; + 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; int rc; - + if (session->kexinit_state == libssh2_NB_state_idle) { - 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; - + 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; + s = data = LIBSSH2_ALLOC(session, data_len); if (!data) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory", 0); return -1; } - + *(s++) = SSH_MSG_KEXINIT; - + 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); - + 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; - + /* 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) */ - + 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); @@ -952,43 +1134,46 @@ static int libssh2_kexinit(LIBSSH2_SESSION *session) p += lang_sc_len + 4; } #endif /* LIBSSH2DEBUG */ - + session->kexinit_state = libssh2_NB_state_created; } else { data = session->kexinit_data; data_len = session->kexinit_data_len; } - + if ((rc = libssh2_packet_write(session, data, data_len)) == PACKET_EAGAIN) { session->kexinit_data = data; session->kexinit_data_len = data_len; return PACKET_EAGAIN; } else if (rc) { LIBSSH2_FREE(session, data); - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send KEXINIT packet to remote host", 0); + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send KEXINIT packet to remote host", 0); session->kexinit_state = libssh2_NB_state_idle; return -1; } - + if (session->local.kexinit) { LIBSSH2_FREE(session, session->local.kexinit); } - + session->local.kexinit = data; session->local.kexinit_len = data_len; - + session->kexinit_state = libssh2_NB_state_idle; - + 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) +static unsigned char * +libssh2_kex_agree_instr(unsigned char *haystack, unsigned long haystack_len, + const unsigned char *needle, unsigned long needle_len) { unsigned char *s; @@ -998,7 +1183,7 @@ static unsigned char *libssh2_kex_agree_instr(unsigned char *haystack, unsigned } /* Needle at start of haystack */ - if ((strncmp((char *)haystack, (char *)needle, needle_len) == 0) && + if ((strncmp((char *) haystack, (char *) needle, needle_len) == 0) && (needle_len == haystack_len || haystack[needle_len] == ',')) { return haystack; } @@ -1006,23 +1191,27 @@ static unsigned char *libssh2_kex_agree_instr(unsigned char *haystack, unsigned s = haystack; /* Search until we run out of comas or we run out of haystack, whichever comes first */ - while ((s = (unsigned char *)strchr((char *)s, ',')) && ((haystack_len - (s - haystack)) > needle_len)) { + while ((s = (unsigned char *) strchr((char *) s, ',')) + && ((haystack_len - (s - haystack)) > needle_len)) { s++; /* Needle at X position */ - if ((strncmp((char *)s, (char *)needle, needle_len) == 0) && - (((s - haystack) + needle_len) == haystack_len || s[needle_len] == ',')) { + if ((strncmp((char *) s, (char *) needle, needle_len) == 0) && + (((s - haystack) + needle_len) == haystack_len + || s[needle_len] == ',')) { return s; } } return NULL; } + /* }}} */ /* {{{ libssh2_get_method_by_name */ -static const -LIBSSH2_COMMON_METHOD *libssh2_get_method_by_name(const char *name, int name_len, const LIBSSH2_COMMON_METHOD **methodlist) +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) && @@ -1033,27 +1222,31 @@ LIBSSH2_COMMON_METHOD *libssh2_get_method_by_name(const char *name, int name_len } return NULL; } + /* }}} */ /* {{{ libssh2_kex_agree_hostkey * Agree on a Hostkey which works with this kex */ static int -libssh2_kex_agree_hostkey(LIBSSH2_SESSION *session, unsigned long kex_flags, unsigned char *hostkey, unsigned long hostkey_len) +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(); + const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods(); unsigned char *s; if (session->hostkey_prefs) { - s = (unsigned char *)session->hostkey_prefs; + s = (unsigned char *) session->hostkey_prefs; while (s && *s) { - unsigned char *p = (unsigned char *)strchr((char *)s, ','); - int method_len = (p ? (p - s) : strlen((char *)s)); + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + int method_len = (p ? (p - s) : strlen((char *) 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((char *)s, method_len, - (const LIBSSH2_COMMON_METHOD**)hostkeyp); + (const LIBSSH2_HOSTKEY_METHOD *) + libssh2_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + hostkeyp); if (!method) { /* Invalid method -- Should never be reached */ @@ -1061,11 +1254,11 @@ libssh2_kex_agree_hostkey(LIBSSH2_SESSION *session, unsigned long kex_flags, uns } /* 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)) { + 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)) { + 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; @@ -1079,14 +1272,16 @@ libssh2_kex_agree_hostkey(LIBSSH2_SESSION *session, unsigned long kex_flags, uns } while (hostkeyp && (*hostkeyp)->name) { - s = libssh2_kex_agree_instr(hostkey, hostkey_len, (unsigned char *)(*hostkeyp)->name, strlen((*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)) { + 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; @@ -1098,27 +1293,31 @@ libssh2_kex_agree_hostkey(LIBSSH2_SESSION *session, unsigned long kex_flags, uns return -1; } + /* }}} */ /* {{{ libssh2_kex_agree_kex_hostkey * 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) +static int +libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex, + unsigned long kex_len, unsigned char *hostkey, + unsigned long hostkey_len) { const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods; unsigned char *s; if (session->kex_prefs) { - s = (unsigned char *)session->kex_prefs; + s = (unsigned char *) session->kex_prefs; while (s && *s) { - unsigned char *q, *p = (unsigned char *)strchr((char *)s, ','); - int method_len = (p ? (p - s) : strlen((char *)s)); + unsigned char *q, *p = (unsigned char *) strchr((char *) s, ','); + int method_len = (p ? (p - s) : strlen((char *) 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((char *)s, method_len, - (const LIBSSH2_COMMON_METHOD**)kexp); + const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *) + libssh2_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + kexp); if (!method) { /* Invalid method -- Should never be reached */ @@ -1128,7 +1327,8 @@ static int libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION *session, unsigned char /* 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) { + 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, @@ -1146,12 +1346,15 @@ static int libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION *session, unsigned char } while (*kexp && (*kexp)->name) { - s = libssh2_kex_agree_instr(kex, kex_len, (unsigned char *)(*kexp)->name, strlen((*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) { + 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, @@ -1166,30 +1369,35 @@ static int libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION *session, unsigned char } return -1; } + /* }}} */ /* {{{ libssh2_kex_agree_crypt * 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) +static int +libssh2_kex_agree_crypt(LIBSSH2_SESSION * session, + libssh2_endpoint_data * endpoint, unsigned char *crypt, + unsigned long crypt_len) { const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods(); unsigned char *s; - - (void)session; + + (void) session; if (endpoint->crypt_prefs) { - s = (unsigned char *)endpoint->crypt_prefs; + s = (unsigned char *) endpoint->crypt_prefs; while (s && *s) { - unsigned char *p = (unsigned char *)strchr((char *)s, ','); - int method_len = (p ? (p - s) : strlen((char *)s)); + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + int method_len = (p ? (p - s) : strlen((char *) 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); + (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 */ @@ -1206,7 +1414,9 @@ static int libssh2_kex_agree_crypt(LIBSSH2_SESSION *session, libssh2_endpoint_da } while (*cryptp && (*cryptp)->name) { - s = libssh2_kex_agree_instr(crypt, crypt_len, (unsigned char *)(*cryptp)->name, strlen((*cryptp)->name)); + s = libssh2_kex_agree_instr(crypt, crypt_len, + (unsigned char *) (*cryptp)->name, + strlen((*cryptp)->name)); if (s) { endpoint->crypt = *cryptp; return 0; @@ -1216,29 +1426,33 @@ static int libssh2_kex_agree_crypt(LIBSSH2_SESSION *session, libssh2_endpoint_da return -1; } + /* }}} */ /* {{{ libssh2_kex_agree_mac * Agree on a message authentication hash */ -static int -libssh2_kex_agree_mac(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint, unsigned char *mac, unsigned long mac_len) +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; + (void) session; if (endpoint->mac_prefs) { - s = (unsigned char *)endpoint->mac_prefs; + s = (unsigned char *) endpoint->mac_prefs; while (s && *s) { - unsigned char *p = (unsigned char *)strchr((char *)s, ','); - int method_len = (p ? (p - s) : strlen((char *)s)); + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + int method_len = (p ? (p - s) : strlen((char *) 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((char *)s, method_len, - (const LIBSSH2_COMMON_METHOD**)macp); + const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *) + libssh2_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + macp); if (!method) { /* Invalid method -- Should never be reached */ @@ -1255,7 +1469,9 @@ libssh2_kex_agree_mac(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint, } while (*macp && (*macp)->name) { - s = libssh2_kex_agree_instr(mac, mac_len, (unsigned char *)(*macp)->name, strlen((*macp)->name)); + s = libssh2_kex_agree_instr(mac, mac_len, + (unsigned char *) (*macp)->name, + strlen((*macp)->name)); if (s) { endpoint->mac = *macp; return 0; @@ -1265,29 +1481,34 @@ libssh2_kex_agree_mac(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint, return -1; } + /* }}} */ /* {{{ libssh2_kex_agree_comp * Agree on a compression scheme */ static int -libssh2_kex_agree_comp(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint, unsigned char *comp, unsigned long comp_len) +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; + (void) session; if (endpoint->comp_prefs) { - s = (unsigned char *)endpoint->comp_prefs; + s = (unsigned char *) endpoint->comp_prefs; while (s && *s) { - unsigned char *p = (unsigned char *)strchr((char *)s, ','); - int method_len = (p ? (p - s) : strlen((char *)s)); + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + int method_len = (p ? (p - s) : strlen((char *) 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((char *)s, method_len, - (const LIBSSH2_COMMON_METHOD**)compp); + (const LIBSSH2_COMP_METHOD *) + libssh2_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + compp); if (!method) { /* Invalid method -- Should never be reached */ @@ -1304,7 +1525,9 @@ libssh2_kex_agree_comp(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint } while (*compp && (*compp)->name) { - s = libssh2_kex_agree_instr(comp, comp_len, (unsigned char *)(*compp)->name, strlen((*compp)->name)); + s = libssh2_kex_agree_instr(comp, comp_len, + (unsigned char *) (*compp)->name, + strlen((*compp)->name)); if (s) { endpoint->comp = *compp; return 0; @@ -1314,6 +1537,7 @@ libssh2_kex_agree_comp(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint return -1; } + /* }}} */ /* TODO: When in server mode we need to turn this logic on its head @@ -1323,9 +1547,12 @@ libssh2_kex_agree_comp(LIBSSH2_SESSION *session, libssh2_endpoint_data *endpoint /* {{{ libssh2_kex_agree_methods * Decide which specific method to use of the methods offered by each party */ -static int libssh2_kex_agree_methods(LIBSSH2_SESSION *session, unsigned char *data, unsigned data_len) +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; + 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; size_t comp_sc_len, mac_cs_len, mac_sc_len, lang_cs_len, lang_sc_len; unsigned char *s = data; @@ -1337,16 +1564,36 @@ static int libssh2_kex_agree_methods(LIBSSH2_SESSION *session, unsigned char *da 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; + 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) @@ -1354,43 +1601,56 @@ static int libssh2_kex_agree_methods(LIBSSH2_SESSION *session, unsigned char *da 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)) { + 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)) { + 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) || + 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)) { + 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)) { + 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 && @@ -1399,20 +1659,23 @@ static int libssh2_kex_agree_methods(LIBSSH2_SESSION *session, unsigned char *da } if (session->remote.comp && session->remote.comp->init && - session->remote.comp->init(session, 0, &session->remote.comp_abstract)) { + session->remote.comp->init(session, 0, + &session->remote.comp_abstract)) { return -1; } return 0; } + /* }}} */ /* {{{ libssh2_kex_exchange * Exchange keys * Returns 0 on success, non-zero on failure */ -int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange, /* session->flags |= SERVER */ - key_exchange_state_t *key_state) +int +libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, /* session->flags |= SERVER */ + key_exchange_state_t * key_state) { int rc = 0; int retcode; @@ -1425,11 +1688,12 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange, /* session->f session->kex = NULL; if (session->hostkey && session->hostkey->dtor) { - session->hostkey->dtor(session, &session->server_hostkey_abstract); + session->hostkey->dtor(session, + &session->server_hostkey_abstract); } session->hostkey = NULL; } - + key_state->state = libssh2_NB_state_created; } @@ -1438,34 +1702,35 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange, /* session->f /* Preserve in case of failure */ key_state->oldlocal = session->local.kexinit; key_state->oldlocal_len = session->local.kexinit_len; - + session->local.kexinit = NULL; - + key_state->state = libssh2_NB_state_sent; } - + if (key_state->state == libssh2_NB_state_sent) { retcode = libssh2_kexinit(session); if (retcode == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (retcode) { + } else if (retcode) { session->local.kexinit = key_state->oldlocal; session->local.kexinit_len = key_state->oldlocal_len; key_state->state = libssh2_NB_state_idle; return -1; } - + key_state->state = libssh2_NB_state_sent1; } if (key_state->state == libssh2_NB_state_sent1) { - retcode = libssh2_packet_require_ex(session, SSH_MSG_KEXINIT, &key_state->data, &key_state->data_len, 0, NULL, 0, - &key_state->req_state); + retcode = + libssh2_packet_require_ex(session, SSH_MSG_KEXINIT, + &key_state->data, + &key_state->data_len, 0, NULL, 0, + &key_state->req_state); if (retcode == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (retcode) { + } else if (retcode) { if (session->local.kexinit) { LIBSSH2_FREE(session, session->local.kexinit); } @@ -1481,10 +1746,11 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange, /* session->f session->remote.kexinit = key_state->data; session->remote.kexinit_len = key_state->data_len; - if (libssh2_kex_agree_methods(session, key_state->data, key_state->data_len)) { + if (libssh2_kex_agree_methods + (session, key_state->data, key_state->data_len)) { rc = -1; } - + key_state->state = libssh2_NB_state_sent2; } } else { @@ -1493,12 +1759,14 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange, /* session->f if (rc == 0) { if (key_state->state == libssh2_NB_state_sent2) { - retcode = session->kex->exchange_keys(session, &key_state->key_state_low); + retcode = + session->kex->exchange_keys(session, + &key_state->key_state_low); if (retcode == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (retcode) { - libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE, "Unrecoverable error exchanging keys", 0); + } else if (retcode) { + libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE, + "Unrecoverable error exchanging keys", 0); rc = -1; } } @@ -1515,81 +1783,86 @@ int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange, /* session->f } session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; - + key_state->state = libssh2_NB_state_idle; return rc; } + /* }}} */ /* {{{ libssh2_session_method_pref * Set preferred method */ -LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method_type, const char *prefs) +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; 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; + 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); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Error allocated space for method preferences", 0); return -1; } memcpy(s, prefs, prefs_len + 1); @@ -1615,7 +1888,9 @@ LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method } if (strlen(newprefs) == 0) { - libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "The requested method(s) are not currently supported", 0); + libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "The requested method(s) are not currently supported", + 0); LIBSSH2_FREE(session, newprefs); return -1; } @@ -1627,4 +1902,5 @@ LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, int method return 0; } + /* }}} */ diff --git a/src/libgcrypt.c b/src/libgcrypt.c index 623a1ad..9da45c5 100644 --- a/src/libgcrypt.c +++ b/src/libgcrypt.c @@ -38,29 +38,29 @@ #include "libssh2_priv.h" #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) +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) { int rc; - (void)e1data; - (void)e1len; - (void)e2data; - (void)e2len; + (void) e1data; + (void) e1len; + (void) e2data; + (void) e2len; if (ddata) { rc = gcry_sexp_build @@ -69,11 +69,10 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, 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); + rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))", + nlen, ndata, elen, edata); } - if (rc) - { + if (rc) { *rsa = NULL; return -1; } @@ -81,11 +80,11 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, 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) +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) { unsigned char hash[SHA_DIGEST_LENGTH]; gcry_sexp_t s_sig, s_hash; @@ -93,38 +92,37 @@ int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, libssh2_sha1(m, m_len, hash); - rc = gcry_sexp_build (&s_hash, NULL, - "(data (flags pkcs1) (hash sha1 %b))", - SHA_DIGEST_LENGTH, 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_sig, NULL, "(sig-val(rsa(s %b)))", - sig_len, sig); + rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig); if (rc != 0) { - gcry_sexp_release (s_hash); + 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; } -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) +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) { int rc; @@ -134,9 +132,9 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx, "(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); + 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) { @@ -147,10 +145,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx, return 0; } -int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, - LIBSSH2_SESSION *session, - FILE *fp, - unsigned const char *passphrase) +int +_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + FILE * fp, unsigned const char *passphrase) { char *data, *save_data; unsigned int datalen; @@ -158,95 +156,94 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, 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); + ret = _libssh2_pem_parse(session, + "-----BEGIN RSA PRIVATE KEY-----", + "-----END RSA PRIVATE KEY-----", + fp, &data, &datalen); if (ret) { return -1; } save_data = data; - if (_libssh2_pem_decode_sequence (&data, &datalen)) { + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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)) { + 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; -fail: - LIBSSH2_FREE (session, save_data); + fail: + 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) +int +_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + FILE * fp, unsigned const char *passphrase) { char *data, *save_data; unsigned int datalen; @@ -254,55 +251,55 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, 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); + ret = _libssh2_pem_parse(session, + "-----BEGIN DSA PRIVATE KEY-----", + "-----END DSA PRIVATE KEY-----", + fp, &data, &datalen); if (ret) { return -1; } save_data = data; - if (_libssh2_pem_decode_sequence (&data, &datalen)) { + 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); + 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); + 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); + 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); + 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); + 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); + ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen); if (ret != 0) { ret = -1; goto fail; @@ -313,25 +310,24 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, goto fail; } - if (_libssh2_dsa_new (dsa, p, plen, q, qlen, - g, glen, y, ylen, x, xlen)) { + if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) { ret = -1; goto fail; } ret = 0; -fail: - LIBSSH2_FREE (session, save_data); + fail: + 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) +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) { gcry_sexp_t sig_sexp; gcry_sexp_t data; @@ -343,15 +339,15 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, return -1; } - if (gcry_sexp_build (&data, NULL, - "(data (flags pkcs1) (hash sha1 %b))", - hash_len, hash)) { + 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; @@ -373,18 +369,18 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, } *signature = LIBSSH2_ALLOC(session, size); - memcpy (*signature, tmp, size); + memcpy(*signature, tmp, size); *signature_len = size; return rc; } -int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char *sig) +int +_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *sig) { - unsigned char zhash[SHA_DIGEST_LENGTH+1]; + unsigned char zhash[SHA_DIGEST_LENGTH + 1]; gcry_sexp_t sig_sexp; gcry_sexp_t data; int ret; @@ -395,17 +391,16 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, return -1; } - memcpy (zhash + 1, hash, hash_len); + memcpy(zhash + 1, hash, hash_len); zhash[0] = 0; - if (gcry_sexp_build (&data, NULL, "(data (value %b))", - hash_len + 1, zhash)) { + 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; @@ -435,13 +430,13 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, 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); + data = gcry_sexp_find_token(sig_sexp, "s", 0); if (!data) { ret = -1; goto out; @@ -463,80 +458,79 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, goto out; } - memcpy (sig + 20, tmp, 20); + memcpy(sig + 20, tmp, 20); ret = 0; -out: + out: if (sig_sexp) { - gcry_sexp_release (sig_sexp); + gcry_sexp_release(sig_sexp); } if (data) { - gcry_sexp_release (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) +int +_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len) { - unsigned char hash[SHA_DIGEST_LENGTH+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); + 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)) { + 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); + 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; } -int _libssh2_cipher_init (_libssh2_cipher_ctx *h, - _libssh2_cipher_type(algo), - unsigned char *iv, - unsigned char *secret, - int encrypt) +int +_libssh2_cipher_init(_libssh2_cipher_ctx * h, + _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 keylen = gcry_cipher_get_algo_keylen(algo); - (void)encrypt; + (void) encrypt; if (algo != GCRY_CIPHER_ARCFOUR) { mode = GCRY_CIPHER_MODE_CBC; } - ret = gcry_cipher_open (h, algo, mode, 0); + ret = gcry_cipher_open(h, algo, mode, 0); if (ret) { return -1; } - ret = gcry_cipher_setkey (*h, secret, keylen); + ret = gcry_cipher_setkey(*h, secret, keylen); if (ret) { - gcry_cipher_close (*h); + 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); + int blklen = gcry_cipher_get_algo_blklen(algo); + ret = gcry_cipher_setiv(*h, iv, blklen); if (ret) { - gcry_cipher_close (*h); + gcry_cipher_close(*h); return -1; } } @@ -544,12 +538,12 @@ int _libssh2_cipher_init (_libssh2_cipher_ctx *h, return 0; } -int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, - _libssh2_cipher_type(algo), - int encrypt, - unsigned char *block) +int +_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block) { - size_t blklen = gcry_cipher_get_algo_blklen (algo); + size_t blklen = gcry_cipher_get_algo_blklen(algo); int ret; if (blklen == 1) { /* Hack for arcfour. */ @@ -557,11 +551,9 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, } if (encrypt) { - ret = gcry_cipher_encrypt (*ctx, block, blklen, - block, blklen); + ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen); } else { - ret = gcry_cipher_decrypt (*ctx, block, blklen, - block, blklen); + ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen); } return ret; } diff --git a/src/libgcrypt.h b/src/libgcrypt.h index 8af17b8..ea53246 100644 --- a/src/libgcrypt.h +++ b/src/libgcrypt.h @@ -93,66 +93,59 @@ #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); -int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, - 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); -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); +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); +int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + 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); +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); #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); -int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, - 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); -int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char *sig); +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); +int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + 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); +int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *sig); #define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx) @@ -167,16 +160,14 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, #define _libssh2_cipher_cast5 GCRY_CIPHER_CAST5 #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); +int _libssh2_cipher_init(_libssh2_cipher_ctx * h, + _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); +int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _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 c8a9e5a..ee06a24 100644 --- a/src/libssh2_priv.h +++ b/src/libssh2_priv.h @@ -115,19 +115,20 @@ #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; typedef int libssh2pack_t; -typedef enum { +typedef enum +{ libssh2_NB_state_idle = 0, libssh2_NB_state_allocated, libssh2_NB_state_created, @@ -144,94 +145,102 @@ typedef enum { libssh2_NB_state_jump3 } libssh2_nonblocking_states; -typedef struct packet_require_state_t { - libssh2_nonblocking_states state; - time_t start; +typedef struct packet_require_state_t +{ + libssh2_nonblocking_states state; + time_t start; } packet_require_state_t; -typedef struct packet_requirev_state_t { - time_t start; +typedef struct packet_requirev_state_t +{ + time_t start; } packet_requirev_state_t; -typedef struct kmdhgGPsha1kex_state_t { - libssh2_nonblocking_states state; - unsigned char *e_packet; - unsigned char *s_packet; - unsigned char *tmp; - unsigned char h_sig_comp[SHA_DIGEST_LENGTH]; - unsigned char c; - unsigned long e_packet_len; - unsigned long s_packet_len; - unsigned long tmp_len; - _libssh2_bn_ctx *ctx; - _libssh2_bn *x; - _libssh2_bn *e; - _libssh2_bn *f; - _libssh2_bn *k; - unsigned char *s; - unsigned char *f_value; - unsigned char *k_value; - unsigned char *h_sig; - unsigned long f_value_len; - unsigned long k_value_len; - unsigned long h_sig_len; - libssh2_sha1_ctx exchange_hash; - packet_require_state_t req_state; - libssh2_nonblocking_states burn_state; +typedef struct kmdhgGPsha1kex_state_t +{ + libssh2_nonblocking_states state; + unsigned char *e_packet; + unsigned char *s_packet; + unsigned char *tmp; + unsigned char h_sig_comp[SHA_DIGEST_LENGTH]; + unsigned char c; + unsigned long e_packet_len; + unsigned long s_packet_len; + unsigned long tmp_len; + _libssh2_bn_ctx *ctx; + _libssh2_bn *x; + _libssh2_bn *e; + _libssh2_bn *f; + _libssh2_bn *k; + unsigned char *s; + unsigned char *f_value; + unsigned char *k_value; + unsigned char *h_sig; + unsigned long f_value_len; + unsigned long k_value_len; + unsigned long h_sig_len; + libssh2_sha1_ctx exchange_hash; + packet_require_state_t req_state; + libssh2_nonblocking_states burn_state; } kmdhgGPsha1kex_state_t; -typedef struct key_exchange_state_low_t { - libssh2_nonblocking_states state; - packet_require_state_t req_state; - kmdhgGPsha1kex_state_t exchange_state; - _libssh2_bn *p; /* SSH2 defined value (p_value) */ - _libssh2_bn *g; /* SSH2 defined value (2) */ - unsigned char request[13]; - unsigned char *data; - unsigned long request_len; - unsigned long data_len; +typedef struct key_exchange_state_low_t +{ + libssh2_nonblocking_states state; + packet_require_state_t req_state; + kmdhgGPsha1kex_state_t exchange_state; + _libssh2_bn *p; /* SSH2 defined value (p_value) */ + _libssh2_bn *g; /* SSH2 defined value (2) */ + unsigned char request[13]; + unsigned char *data; + unsigned long request_len; + unsigned long data_len; } key_exchange_state_low_t; -typedef struct key_exchange_state_t { - libssh2_nonblocking_states state; - packet_require_state_t req_state; - key_exchange_state_low_t key_state_low; - unsigned char *data; - unsigned long data_len; - unsigned char *oldlocal; - unsigned long oldlocal_len; +typedef struct key_exchange_state_t +{ + libssh2_nonblocking_states state; + packet_require_state_t req_state; + key_exchange_state_low_t key_state_low; + unsigned char *data; + unsigned long data_len; + unsigned char *oldlocal; + unsigned long oldlocal_len; } key_exchange_state_t; #define FwdNotReq "Forward not requested" -typedef struct packet_queue_listener_state_t { - libssh2_nonblocking_states state; - unsigned char packet[17 + (sizeof(FwdNotReq) - 1)]; - unsigned char *host; - unsigned char *shost; - uint32_t sender_channel; - uint32_t initial_window_size; - uint32_t packet_size; - uint32_t port; - uint32_t sport; - uint32_t host_len; - uint32_t shost_len; +typedef struct packet_queue_listener_state_t +{ + libssh2_nonblocking_states state; + unsigned char packet[17 + (sizeof(FwdNotReq) - 1)]; + unsigned char *host; + unsigned char *shost; + uint32_t sender_channel; + uint32_t initial_window_size; + uint32_t packet_size; + uint32_t port; + uint32_t sport; + uint32_t host_len; + uint32_t shost_len; } packet_queue_listener_state_t; #define X11FwdUnAvil "X11 Forward Unavailable" -typedef struct packet_x11_open_state_t { - libssh2_nonblocking_states state; - unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)]; - unsigned char *shost; - uint32_t sender_channel; - uint32_t initial_window_size; - uint32_t packet_size; - uint32_t sport; - uint32_t shost_len; +typedef struct packet_x11_open_state_t +{ + libssh2_nonblocking_states state; + unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)]; + unsigned char *shost; + uint32_t sender_channel; + uint32_t initial_window_size; + uint32_t packet_size; + uint32_t sport; + uint32_t shost_len; } packet_x11_open_state_t; -struct _LIBSSH2_PACKET { +struct _LIBSSH2_PACKET +{ unsigned char type; /* Unencrypted Payload (no type byte, no padding, just the facts ma'am) */ @@ -250,11 +259,13 @@ struct _LIBSSH2_PACKET { LIBSSH2_PACKET *next, *prev; }; -struct _LIBSSH2_PACKET_BRIGADE { +struct _LIBSSH2_PACKET_BRIGADE +{ LIBSSH2_PACKET *head, *tail; }; -typedef struct _libssh2_channel_data { +typedef struct _libssh2_channel_data +{ /* Identifier */ unsigned long id; @@ -265,7 +276,8 @@ typedef struct _libssh2_channel_data { char close, eof, extended_data_ignore_mode; } libssh2_channel_data; -struct _LIBSSH2_CHANNEL { +struct _LIBSSH2_CHANNEL +{ unsigned char *channel_type; unsigned channel_type_len; @@ -281,85 +293,87 @@ struct _LIBSSH2_CHANNEL { LIBSSH2_CHANNEL *next, *prev; void *abstract; - LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb)); - + LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb)); + /* State variables used in libssh2_channel_setenv_ex() */ - libssh2_nonblocking_states setenv_state; - unsigned char *setenv_packet; - unsigned long setenv_packet_len; - unsigned char setenv_local_channel[4]; - packet_requirev_state_t setenv_packet_requirev_state; - + libssh2_nonblocking_states setenv_state; + unsigned char *setenv_packet; + unsigned long setenv_packet_len; + unsigned char setenv_local_channel[4]; + packet_requirev_state_t setenv_packet_requirev_state; + /* State variables used in libssh2_channel_request_pty_ex() */ - libssh2_nonblocking_states reqPTY_state; - unsigned char *reqPTY_packet; - unsigned long reqPTY_packet_len; - unsigned char reqPTY_local_channel[4]; - packet_requirev_state_t reqPTY_packet_requirev_state; - + libssh2_nonblocking_states reqPTY_state; + unsigned char *reqPTY_packet; + unsigned long reqPTY_packet_len; + unsigned char reqPTY_local_channel[4]; + packet_requirev_state_t reqPTY_packet_requirev_state; + /* State variables used in libssh2_channel_x11_req_ex() */ - libssh2_nonblocking_states reqX11_state; - unsigned char *reqX11_packet; - unsigned long reqX11_packet_len; - unsigned char reqX11_local_channel[4]; - packet_requirev_state_t reqX11_packet_requirev_state; - + libssh2_nonblocking_states reqX11_state; + unsigned char *reqX11_packet; + unsigned long reqX11_packet_len; + unsigned char reqX11_local_channel[4]; + packet_requirev_state_t reqX11_packet_requirev_state; + /* State variables used in libssh2_channel_process_startup() */ - libssh2_nonblocking_states process_state; - unsigned char *process_packet; - unsigned long process_packet_len; - unsigned char process_local_channel[4]; - packet_requirev_state_t process_packet_requirev_state; - + libssh2_nonblocking_states process_state; + unsigned char *process_packet; + unsigned long process_packet_len; + unsigned char process_local_channel[4]; + packet_requirev_state_t process_packet_requirev_state; + /* State variables used in libssh2_channel_flush_ex() */ - libssh2_nonblocking_states flush_state; - unsigned long flush_refund_bytes; - unsigned long flush_flush_bytes; - + libssh2_nonblocking_states flush_state; + unsigned long flush_refund_bytes; + unsigned long flush_flush_bytes; + /* State variables used in libssh2_channel_receive_window_adjust() */ - libssh2_nonblocking_states adjust_state; - unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */ - + libssh2_nonblocking_states adjust_state; + unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */ + /* State variables used in libssh2_channel_read_ex() */ - libssh2_nonblocking_states read_state; - LIBSSH2_PACKET *read_packet; - LIBSSH2_PACKET *read_next; - int read_block; - int read_bytes_read; - uint32_t read_local_id; - int read_want; - int read_unlink_packet; - + libssh2_nonblocking_states read_state; + LIBSSH2_PACKET *read_packet; + LIBSSH2_PACKET *read_next; + int read_block; + int read_bytes_read; + uint32_t read_local_id; + int read_want; + int read_unlink_packet; + /* State variables used in libssh2_channel_write_ex() */ - libssh2_nonblocking_states write_state; - unsigned char *write_packet; - unsigned char *write_s; - unsigned long write_packet_len; - unsigned long write_bufwrote; - size_t write_bufwrite; - + libssh2_nonblocking_states write_state; + unsigned char *write_packet; + unsigned char *write_s; + unsigned long write_packet_len; + unsigned long write_bufwrote; + size_t write_bufwrite; + /* State variables used in libssh2_channel_close() */ - libssh2_nonblocking_states close_state; - unsigned char close_packet[5]; + libssh2_nonblocking_states close_state; + unsigned char close_packet[5]; /* State variables used in libssh2_channel_wait_closedeof() */ - libssh2_nonblocking_states wait_eof_state; - + libssh2_nonblocking_states wait_eof_state; + /* State variables used in libssh2_channel_wait_closed() */ - libssh2_nonblocking_states wait_closed_state; - + libssh2_nonblocking_states wait_closed_state; + /* State variables used in libssh2_channel_free() */ - libssh2_nonblocking_states free_state; - + libssh2_nonblocking_states free_state; + /* State variables used in libssh2_channel_handle_extended_data2() */ - libssh2_nonblocking_states extData2_state; + libssh2_nonblocking_states extData2_state; }; -struct _LIBSSH2_CHANNEL_BRIGADE { +struct _LIBSSH2_CHANNEL_BRIGADE +{ LIBSSH2_CHANNEL *head, *tail; }; -struct _LIBSSH2_LISTENER { +struct _LIBSSH2_LISTENER +{ LIBSSH2_SESSION *session; char *host; @@ -370,14 +384,15 @@ struct _LIBSSH2_LISTENER { int queue_maxsize; LIBSSH2_LISTENER *prev, *next; - + /* State variables used in libssh2_channel_forward_cancel() */ - libssh2_nonblocking_states chanFwdCncl_state; - unsigned char *chanFwdCncl_data; - size_t chanFwdCncl_data_len; + libssh2_nonblocking_states chanFwdCncl_state; + unsigned char *chanFwdCncl_data; + size_t chanFwdCncl_data_len; }; -typedef struct _libssh2_endpoint_data { +typedef struct _libssh2_endpoint_data +{ unsigned char *banner; unsigned char *kexinit; @@ -402,187 +417,195 @@ typedef struct _libssh2_endpoint_data { #define PACKETBUFSIZE 4096 -struct transportpacket { +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 */ + 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 */ + 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_PUBLICKEY { +struct _LIBSSH2_PUBLICKEY +{ LIBSSH2_CHANNEL *channel; unsigned long version; - + /* State variables used in libssh2_publickey_packet_receive() */ - libssh2_nonblocking_states receive_state; - unsigned char *receive_packet; - unsigned long receive_packet_len; - + libssh2_nonblocking_states receive_state; + unsigned char *receive_packet; + unsigned long receive_packet_len; + /* State variables used in libssh2_publickey_add_ex() */ - libssh2_nonblocking_states add_state; - unsigned char *add_packet; - unsigned char *add_s; - + libssh2_nonblocking_states add_state; + unsigned char *add_packet; + unsigned char *add_s; + /* State variables used in libssh2_publickey_remove_ex() */ - libssh2_nonblocking_states remove_state; - unsigned char *remove_packet; - unsigned char *remove_s; - + libssh2_nonblocking_states remove_state; + unsigned char *remove_packet; + unsigned char *remove_s; + /* State variables used in libssh2_publickey_list_fetch() */ - libssh2_nonblocking_states listFetch_state; - unsigned char *listFetch_s; - unsigned char listFetch_buffer[12]; - unsigned char *listFetch_data; - unsigned long listFetch_data_len; + libssh2_nonblocking_states listFetch_state; + unsigned char *listFetch_s; + unsigned char listFetch_buffer[12]; + unsigned char *listFetch_data; + unsigned long listFetch_data_len; }; -struct _LIBSSH2_SFTP_HANDLE { +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 { + + union _libssh2_sftp_handle_data + { + struct _libssh2_sftp_handle_file_data + { libssh2_uint64_t offset; } file; - struct _libssh2_sftp_handle_dir_data { + struct _libssh2_sftp_handle_dir_data + { unsigned long names_left; void *names_packet; char *next_name; } dir; } u; - + /* State variables used in libssh2_sftp_close_handle() */ - libssh2_nonblocking_states close_state; - unsigned long close_request_id; - unsigned char *close_packet; + libssh2_nonblocking_states close_state; + unsigned long close_request_id; + unsigned char *close_packet; }; -struct _LIBSSH2_SFTP { +struct _LIBSSH2_SFTP +{ LIBSSH2_CHANNEL *channel; - + unsigned long request_id, version; - + LIBSSH2_PACKET_BRIGADE packets; - + LIBSSH2_SFTP_HANDLE *handles; - + unsigned long last_errno; - + /* Holder for partial packet, use in libssh2_sftp_packet_read() */ - unsigned char *partial_packet; /* The data */ - unsigned long partial_len; /* Desired number of bytes */ - unsigned long partial_received; /* Bytes received so far */ - + unsigned char *partial_packet; /* The data */ + unsigned long partial_len; /* Desired number of bytes */ + unsigned long partial_received; /* Bytes received so far */ + /* Time that libssh2_sftp_packet_requirev() started reading */ - time_t requirev_start; - + time_t requirev_start; + /* State variables used in libssh2_sftp_open_ex() */ - libssh2_nonblocking_states open_state; - unsigned char *open_packet; - ssize_t open_packet_len; - unsigned long open_request_id; - + libssh2_nonblocking_states open_state; + unsigned char *open_packet; + ssize_t open_packet_len; + unsigned long open_request_id; + /* State variables used in libssh2_sftp_read() */ - libssh2_nonblocking_states read_state; - unsigned char *read_packet; - unsigned long read_request_id; - size_t read_total_read; - + libssh2_nonblocking_states read_state; + unsigned char *read_packet; + unsigned long read_request_id; + size_t read_total_read; + /* State variables used in libssh2_sftp_readdir() */ - libssh2_nonblocking_states readdir_state; - unsigned char *readdir_packet; - unsigned long readdir_request_id; - + libssh2_nonblocking_states readdir_state; + unsigned char *readdir_packet; + unsigned long readdir_request_id; + /* State variables used in libssh2_sftp_write() */ - libssh2_nonblocking_states write_state; - unsigned char *write_packet; - unsigned long write_request_id; - + libssh2_nonblocking_states write_state; + unsigned char *write_packet; + unsigned long write_request_id; + /* State variables used in libssh2_sftp_fstat_ex() */ - libssh2_nonblocking_states fstat_state; - unsigned char *fstat_packet; - unsigned long fstat_request_id; - + libssh2_nonblocking_states fstat_state; + unsigned char *fstat_packet; + unsigned long fstat_request_id; + /* State variables used in libssh2_sftp_unlink_ex() */ - libssh2_nonblocking_states unlink_state; - unsigned char *unlink_packet; - unsigned long unlink_request_id; - + libssh2_nonblocking_states unlink_state; + unsigned char *unlink_packet; + unsigned long unlink_request_id; + /* State variables used in libssh2_sftp_rename_ex() */ - libssh2_nonblocking_states rename_state; - unsigned char *rename_packet; - unsigned char *rename_s; - unsigned long rename_request_id; - + libssh2_nonblocking_states rename_state; + unsigned char *rename_packet; + unsigned char *rename_s; + unsigned long rename_request_id; + /* State variables used in libssh2_sftp_mkdir() */ - libssh2_nonblocking_states mkdir_state; - unsigned char *mkdir_packet; - unsigned long mkdir_request_id; - + libssh2_nonblocking_states mkdir_state; + unsigned char *mkdir_packet; + unsigned long mkdir_request_id; + /* State variables used in libssh2_sftp_rmdir() */ - libssh2_nonblocking_states rmdir_state; - unsigned char *rmdir_packet; - unsigned long rmdir_request_id; - + libssh2_nonblocking_states rmdir_state; + unsigned char *rmdir_packet; + unsigned long rmdir_request_id; + /* State variables used in libssh2_sftp_stat() */ - libssh2_nonblocking_states stat_state; - unsigned char *stat_packet; - unsigned long stat_request_id; - + libssh2_nonblocking_states stat_state; + unsigned char *stat_packet; + unsigned long stat_request_id; + /* State variables used in libssh2_sftp_symlink() */ - libssh2_nonblocking_states symlink_state; - unsigned char *symlink_packet; - unsigned long symlink_request_id; + libssh2_nonblocking_states symlink_state; + unsigned char *symlink_packet; + unsigned long symlink_request_id; }; #define LIBSSH2_SCP_RESPONSE_BUFLEN 256 -struct _LIBSSH2_SESSION { +struct _LIBSSH2_SESSION +{ /* Memory management callbacks */ void *abstract; - LIBSSH2_ALLOC_FUNC((*alloc)); - LIBSSH2_REALLOC_FUNC((*realloc)); - LIBSSH2_FREE_FUNC((*free)); + 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)); + 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; @@ -609,7 +632,7 @@ struct _LIBSSH2_SESSION { unsigned long server_hostkey_len; #if LIBSSH2_MD5 unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH]; -#endif /* ! LIBSSH2_MD5 */ +#endif /* ! LIBSSH2_MD5 */ unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH]; /* (remote as source of data -- packet_read ) */ @@ -641,169 +664,169 @@ struct _LIBSSH2_SESSION { /* 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 /* State variables used in libssh2_banner_send() */ - libssh2_nonblocking_states banner_TxRx_state; - char banner_TxRx_banner[256]; - ssize_t banner_TxRx_total_send; - + libssh2_nonblocking_states banner_TxRx_state; + char banner_TxRx_banner[256]; + ssize_t banner_TxRx_total_send; + /* State variables used in libssh2_kexinit() */ - libssh2_nonblocking_states kexinit_state; - unsigned char *kexinit_data; - size_t kexinit_data_len; - + libssh2_nonblocking_states kexinit_state; + unsigned char *kexinit_data; + size_t kexinit_data_len; + /* State variables used in libssh2_session_startup() */ - libssh2_nonblocking_states startup_state; - unsigned char *startup_data; - unsigned long startup_data_len; - unsigned char startup_service[sizeof("ssh-userauth") + 5 - 1]; - unsigned long startup_service_length; - packet_require_state_t startup_req_state; - key_exchange_state_t startup_key_state; - + libssh2_nonblocking_states startup_state; + unsigned char *startup_data; + unsigned long startup_data_len; + unsigned char startup_service[sizeof("ssh-userauth") + 5 - 1]; + unsigned long startup_service_length; + packet_require_state_t startup_req_state; + key_exchange_state_t startup_key_state; + /* State variables used in libssh2_session_free() */ - libssh2_nonblocking_states free_state; - + libssh2_nonblocking_states free_state; + /* State variables used in libssh2_session_disconnect_ex() */ - libssh2_nonblocking_states disconnect_state; - unsigned char *disconnect_data; - unsigned long disconnect_data_len; + libssh2_nonblocking_states disconnect_state; + unsigned char *disconnect_data; + unsigned long disconnect_data_len; /* State variables used in libssh2_packet_read() */ - libssh2_nonblocking_states readPack_state; - int readPack_encrypted; + libssh2_nonblocking_states readPack_state; + int readPack_encrypted; /* State variables used in libssh2_userauth_list() */ - libssh2_nonblocking_states userauth_list_state; - unsigned char *userauth_list_data; - unsigned long userauth_list_data_len; - packet_requirev_state_t userauth_list_packet_requirev_state; - + libssh2_nonblocking_states userauth_list_state; + unsigned char *userauth_list_data; + unsigned long userauth_list_data_len; + packet_requirev_state_t userauth_list_packet_requirev_state; + /* State variables used in libssh2_userauth_password_ex() */ - libssh2_nonblocking_states userauth_pswd_state; - unsigned char *userauth_pswd_data; - unsigned char userauth_pswd_data0; - unsigned long userauth_pswd_data_len; - char *userauth_pswd_newpw; - int userauth_pswd_newpw_len; - packet_requirev_state_t userauth_pswd_packet_requirev_state; - + libssh2_nonblocking_states userauth_pswd_state; + unsigned char *userauth_pswd_data; + unsigned char userauth_pswd_data0; + unsigned long userauth_pswd_data_len; + char *userauth_pswd_newpw; + int userauth_pswd_newpw_len; + packet_requirev_state_t userauth_pswd_packet_requirev_state; + /* State variables used in libssh2_userauth_hostbased_fromfile_ex() */ - libssh2_nonblocking_states userauth_host_state; - unsigned char *userauth_host_data; - unsigned long userauth_host_data_len; - unsigned char *userauth_host_packet; - unsigned long userauth_host_packet_len; - unsigned char *userauth_host_method; - unsigned long userauth_host_method_len; - unsigned char *userauth_host_s; - packet_requirev_state_t userauth_host_packet_requirev_state; - + libssh2_nonblocking_states userauth_host_state; + unsigned char *userauth_host_data; + unsigned long userauth_host_data_len; + unsigned char *userauth_host_packet; + unsigned long userauth_host_packet_len; + unsigned char *userauth_host_method; + unsigned long userauth_host_method_len; + unsigned char *userauth_host_s; + packet_requirev_state_t userauth_host_packet_requirev_state; + /* State variables used in libssh2_userauth_publickey_fromfile_ex() */ - libssh2_nonblocking_states userauth_pblc_state; - unsigned char *userauth_pblc_data; - unsigned long userauth_pblc_data_len; - unsigned char *userauth_pblc_packet; - unsigned long userauth_pblc_packet_len; - unsigned char *userauth_pblc_method; - unsigned long userauth_pblc_method_len; - unsigned char *userauth_pblc_s; - unsigned char *userauth_pblc_b; - packet_requirev_state_t userauth_pblc_packet_requirev_state; - + libssh2_nonblocking_states userauth_pblc_state; + unsigned char *userauth_pblc_data; + unsigned long userauth_pblc_data_len; + unsigned char *userauth_pblc_packet; + unsigned long userauth_pblc_packet_len; + unsigned char *userauth_pblc_method; + unsigned long userauth_pblc_method_len; + unsigned char *userauth_pblc_s; + unsigned char *userauth_pblc_b; + packet_requirev_state_t userauth_pblc_packet_requirev_state; + /* State variables used in llibssh2_userauth_keyboard_interactive_ex() */ - libssh2_nonblocking_states userauth_kybd_state; - unsigned char *userauth_kybd_data; - unsigned long userauth_kybd_data_len; - unsigned char *userauth_kybd_packet; - unsigned long userauth_kybd_packet_len; - unsigned int userauth_kybd_auth_name_len; - char *userauth_kybd_auth_name; - unsigned userauth_kybd_auth_instruction_len; - char *userauth_kybd_auth_instruction; - unsigned int userauth_kybd_num_prompts; - int userauth_kybd_auth_failure; - LIBSSH2_USERAUTH_KBDINT_PROMPT *userauth_kybd_prompts; - LIBSSH2_USERAUTH_KBDINT_RESPONSE *userauth_kybd_responses; - packet_requirev_state_t userauth_kybd_packet_requirev_state; - + libssh2_nonblocking_states userauth_kybd_state; + unsigned char *userauth_kybd_data; + unsigned long userauth_kybd_data_len; + unsigned char *userauth_kybd_packet; + unsigned long userauth_kybd_packet_len; + unsigned int userauth_kybd_auth_name_len; + char *userauth_kybd_auth_name; + unsigned userauth_kybd_auth_instruction_len; + char *userauth_kybd_auth_instruction; + unsigned int userauth_kybd_num_prompts; + int userauth_kybd_auth_failure; + LIBSSH2_USERAUTH_KBDINT_PROMPT *userauth_kybd_prompts; + LIBSSH2_USERAUTH_KBDINT_RESPONSE *userauth_kybd_responses; + packet_requirev_state_t userauth_kybd_packet_requirev_state; + /* State variables used in libssh2_channel_open_ex() */ - libssh2_nonblocking_states open_state; - packet_requirev_state_t open_packet_requirev_state; - LIBSSH2_CHANNEL *open_channel; - unsigned char *open_packet; - unsigned long open_packet_len; - unsigned char *open_data; - unsigned long open_data_len; - unsigned long open_local_channel; - + libssh2_nonblocking_states open_state; + packet_requirev_state_t open_packet_requirev_state; + LIBSSH2_CHANNEL *open_channel; + unsigned char *open_packet; + unsigned long open_packet_len; + unsigned char *open_data; + unsigned long open_data_len; + unsigned long open_local_channel; + /* State variables used in libssh2_channel_direct_tcpip_ex() */ - libssh2_nonblocking_states direct_state; - unsigned char *direct_message; - unsigned long direct_host_len; - unsigned long direct_shost_len; - unsigned long direct_message_len; - + libssh2_nonblocking_states direct_state; + unsigned char *direct_message; + unsigned long direct_host_len; + unsigned long direct_shost_len; + unsigned long direct_message_len; + /* State variables used in libssh2_channel_forward_listen_ex() */ - libssh2_nonblocking_states fwdLstn_state; - unsigned char *fwdLstn_packet; - unsigned long fwdLstn_host_len; - unsigned long fwdLstn_packet_len; - packet_requirev_state_t fwdLstn_packet_requirev_state; - + libssh2_nonblocking_states fwdLstn_state; + unsigned char *fwdLstn_packet; + unsigned long fwdLstn_host_len; + unsigned long fwdLstn_packet_len; + packet_requirev_state_t fwdLstn_packet_requirev_state; + /* State variables used in libssh2_publickey_init() */ - libssh2_nonblocking_states pkeyInit_state; - LIBSSH2_PUBLICKEY *pkeyInit_pkey; - LIBSSH2_CHANNEL *pkeyInit_channel; - unsigned char *pkeyInit_data; - unsigned long pkeyInit_data_len; - + libssh2_nonblocking_states pkeyInit_state; + LIBSSH2_PUBLICKEY *pkeyInit_pkey; + LIBSSH2_CHANNEL *pkeyInit_channel; + unsigned char *pkeyInit_data; + unsigned long pkeyInit_data_len; + /* State variables used in libssh2_packet_add() */ - libssh2_nonblocking_states packAdd_state; - LIBSSH2_PACKET *packAdd_packet; - LIBSSH2_CHANNEL *packAdd_channel; - unsigned long packAdd_data_head; - key_exchange_state_t packAdd_key_state; - packet_queue_listener_state_t packAdd_Qlstn_state; - packet_x11_open_state_t packAdd_x11open_state; - + libssh2_nonblocking_states packAdd_state; + LIBSSH2_PACKET *packAdd_packet; + LIBSSH2_CHANNEL *packAdd_channel; + unsigned long packAdd_data_head; + key_exchange_state_t packAdd_key_state; + packet_queue_listener_state_t packAdd_Qlstn_state; + packet_x11_open_state_t packAdd_x11open_state; + /* State variables used in fullpacket() */ - libssh2_nonblocking_states fullpacket_state; - int fullpacket_macstate; - int fullpacket_payload_len; - libssh2pack_t fullpacket_packet_type; - + libssh2_nonblocking_states fullpacket_state; + int fullpacket_macstate; + int fullpacket_payload_len; + libssh2pack_t fullpacket_packet_type; + /* State variables used in libssh2_sftp_init() */ - libssh2_nonblocking_states sftpInit_state; - LIBSSH2_SFTP *sftpInit_sftp; - LIBSSH2_CHANNEL *sftpInit_channel; - unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id} + version_id(4) */ - + libssh2_nonblocking_states sftpInit_state; + LIBSSH2_SFTP *sftpInit_sftp; + LIBSSH2_CHANNEL *sftpInit_channel; + unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id} + version_id(4) */ + /* State variables used in libssh2_scp_recv() */ - libssh2_nonblocking_states scpRecv_state; - unsigned char *scpRecv_command; - unsigned long scpRecv_command_len; - unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; - unsigned long scpRecv_response_len; - long scpRecv_mode; - long scpRecv_size; - long scpRecv_mtime; - long scpRecv_atime; - char *scpRecv_err_msg; - long scpRecv_err_len; - LIBSSH2_CHANNEL *scpRecv_channel; - + libssh2_nonblocking_states scpRecv_state; + unsigned char *scpRecv_command; + unsigned long scpRecv_command_len; + unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; + unsigned long scpRecv_response_len; + long scpRecv_mode; + long scpRecv_size; + long scpRecv_mtime; + long scpRecv_atime; + char *scpRecv_err_msg; + long scpRecv_err_len; + LIBSSH2_CHANNEL *scpRecv_channel; + /* State variables used in libssh2_scp_send_ex() */ - libssh2_nonblocking_states scpSend_state; - unsigned char *scpSend_command; - unsigned long scpSend_command_len; - unsigned char scpSend_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; - unsigned long scpSend_response_len; - char *scpSend_err_msg; - long scpSend_err_len; - LIBSSH2_CHANNEL *scpSend_channel; + libssh2_nonblocking_states scpSend_state; + unsigned char *scpSend_command; + unsigned long scpSend_command_len; + unsigned char scpSend_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; + unsigned long scpSend_response_len; + char *scpSend_err_msg; + long scpSend_err_len; + LIBSSH2_CHANNEL *scpSend_channel; }; /* session.state bits */ @@ -823,28 +846,40 @@ struct _LIBSSH2_SESSION { /* libssh2 extensible ssh api, ultimately I'd like to allow loading additional methods via .so/.dll */ -struct _LIBSSH2_KEX_METHOD { +struct _LIBSSH2_KEX_METHOD +{ const char *name; /* Key exchange, populates session->* and returns 0 on success, non-0 on error */ - int (*exchange_keys)(LIBSSH2_SESSION *session, key_exchange_state_low_t *key_state); + int (*exchange_keys) (LIBSSH2_SESSION * session, + key_exchange_state_low_t * key_state); long flags; }; -struct _LIBSSH2_HOSTKEY_METHOD { +struct _LIBSSH2_HOSTKEY_METHOD +{ 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 { +struct _LIBSSH2_CRYPT_METHOD +{ const char *name; int blocksize; @@ -855,23 +890,31 @@ struct _LIBSSH2_CRYPT_METHOD { 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 { +struct _LIBSSH2_COMP_METHOD +{ 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 { +struct _LIBSSH2_MAC_METHOD +{ const char *name; /* The length of a given MAC packet */ @@ -881,9 +924,13 @@ struct _LIBSSH2_MAC_METHOD { 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); + 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 @@ -895,7 +942,8 @@ struct _LIBSSH2_MAC_METHOD { #define LIBSSH2_DBG_ERROR 7 #define LIBSSH2_DBG_PUBLICKEY 8 #ifdef LIBSSH2DEBUG -void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, ...); +void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, + ...); #else #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 style */ @@ -905,8 +953,10 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, const char *format, . #define _libssh2_debug(x,y,z,...) do {} while (0) #else /* no gcc and not C99, do static and hopefully inline */ -static inline void _libssh2_debug(LIBSSH2_SESSION *session, int context, - const char *format, ...) {} +static inline void +_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...) +{ +} #endif #endif @@ -1004,7 +1054,7 @@ static inline void _libssh2_debug(LIBSSH2_SESSION *session, int context, #define SSH_MSG_CHANNEL_SUCCESS 99 #define SSH_MSG_CHANNEL_FAILURE 100 -void libssh2_session_shutdown(LIBSSH2_SESSION *session); +void libssh2_session_shutdown(LIBSSH2_SESSION * session); unsigned long libssh2_ntohu32(const unsigned char *buf); libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf); @@ -1013,7 +1063,7 @@ 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 */ -int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds); +int libssh2_waitsocket(LIBSSH2_SESSION * session, long seconds); /* CAUTION: some of these error codes are returned in the public API and is @@ -1029,27 +1079,49 @@ int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds); #define PACKET_FAIL -1 #define PACKET_NONE 0 -libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session); +libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION * session); -int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, +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); -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); -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, packet_require_state_t *state); -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, packet_requirev_state_t *state); -int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *state); -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); -int libssh2_kex_exchange(LIBSSH2_SESSION *session, int reexchange, key_exchange_state_t *state); -unsigned long libssh2_channel_nextid(LIBSSH2_SESSION *session); -LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long channel_id); -unsigned long libssh2_channel_packet_data_len(LIBSSH2_CHANNEL *channel, int stream_id); +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); +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, + packet_require_state_t * state); +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, + packet_requirev_state_t * state); +int libssh2_packet_burn(LIBSSH2_SESSION * session, + libssh2_nonblocking_states * state); +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); +int libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + key_exchange_state_t * state); +unsigned long libssh2_channel_nextid(LIBSSH2_SESSION * session); +LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION * session, + unsigned long channel_id); +unsigned long libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, + int stream_id); /* this is the lib-internal set blocking function */ -int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking); +int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking); /* Let crypt.c/hostkey.c/comp.c/mac.c expose their method structs */ const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void); @@ -1061,13 +1133,12 @@ const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void); #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); -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); +int _libssh2_pem_parse(LIBSSH2_SESSION * session, + 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); #endif /* LIBSSH2_H */ diff --git a/src/mac.c b/src/mac.c index cac69c1..ed924d7 100644 --- a/src/mac.c +++ b/src/mac.c @@ -41,12 +41,15 @@ /* {{{ libssh2_mac_none_MAC * 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) +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) { return 0; } + /* }}} */ @@ -63,20 +66,24 @@ static LIBSSH2_MAC_METHOD libssh2_mac_method_none = { /* {{{ libssh2_mac_method_common_init * Initialize simple mac methods */ -static int libssh2_mac_method_common_init(LIBSSH2_SESSION *session, unsigned char *key, int *free_key, void **abstract) +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; + (void) session; return 0; } + /* }}} */ /* {{{ libssh2_mac_method_common_dtor * Cleanup simple mac methods */ -static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstract) +static int +libssh2_mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract) { if (*abstract) { LIBSSH2_FREE(session, *abstract); @@ -85,18 +92,23 @@ static int libssh2_mac_method_common_dtor(LIBSSH2_SESSION *session, void **abstr return 0; } + /* }}} */ /* {{{ libssh2_mac_method_hmac_sha1_hash * 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) +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) { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; - (void)session; + (void) session; libssh2_htonu32(seqno_buf, seqno); @@ -111,6 +123,7 @@ static int libssh2_mac_method_hmac_sha1_hash(LIBSSH2_SESSION *session, unsigned return 0; } + /* }}} */ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = { @@ -125,17 +138,23 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1 = { /* {{{ 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) +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) { 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; } + /* }}} */ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = { @@ -150,13 +169,17 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_sha1_96 = { /* {{{ 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) +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) { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; - (void)session; + (void) session; libssh2_htonu32(seqno_buf, seqno); @@ -171,6 +194,7 @@ static int libssh2_mac_method_hmac_md5_hash(LIBSSH2_SESSION *session, unsigned c return 0; } + /* }}} */ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = { @@ -185,17 +209,23 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5 = { /* {{{ 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) +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) { 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; } + /* }}} */ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = { @@ -211,13 +241,18 @@ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_md5_96 = { /* {{{ libssh2_mac_method_hmac_ripemd160_hash * 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) +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) { libssh2_hmac_ctx ctx; unsigned char seqno_buf[4]; - (void)session; + (void) session; libssh2_htonu32(seqno_buf, seqno); @@ -232,6 +267,7 @@ static int libssh2_mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION *session, unsi return 0; } + /* }}} */ static const LIBSSH2_MAC_METHOD libssh2_mac_method_hmac_ripemd160 = { @@ -268,7 +304,8 @@ static const LIBSSH2_MAC_METHOD *_libssh2_mac_methods[] = { NULL }; -const LIBSSH2_MAC_METHOD **libssh2_mac_methods(void) { +const LIBSSH2_MAC_METHOD ** +libssh2_mac_methods(void) +{ return _libssh2_mac_methods; } - diff --git a/src/misc.c b/src/misc.c index 77af4c8..05f6329 100644 --- a/src/misc.c +++ b/src/misc.c @@ -42,17 +42,20 @@ /* {{{ libssh2_ntohu32 */ -unsigned long libssh2_ntohu32(const unsigned char *buf) +unsigned long +libssh2_ntohu32(const unsigned char *buf) { return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; } + /* }}} */ /* {{{ libssh2_ntohu64 * Note: Some 32-bit platforms have issues with bitops on long longs * Work around this by doing expensive (but safer) arithmetic ops with optimization defying parentheses */ -libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf) +libssh2_uint64_t +libssh2_ntohu64(const unsigned char *buf) { unsigned long msl, lsl; @@ -61,22 +64,26 @@ libssh2_uint64_t libssh2_ntohu64(const unsigned char *buf) return ((msl * 65536) * 65536) + lsl; } + /* }}} */ /* {{{ libssh2_htonu32 */ -void libssh2_htonu32(unsigned char *buf, unsigned long value) +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; } + /* }}} */ /* {{{ libssh2_htonu64 */ -void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value) +void +libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value) { unsigned long msl = (value / 65536) / 65536; @@ -90,6 +97,7 @@ void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value) buf[6] = (value >> 8) & 0xFF; buf[7] = value & 0xFF; } + /* }}} */ /* Base64 Conversion */ @@ -97,11 +105,11 @@ void libssh2_htonu64(unsigned char *buf, libssh2_uint64_t value) /* {{{ */ static const char libssh2_base64_table[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' - }; + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' +}; static const char libssh2_base64_pad = '='; @@ -110,7 +118,7 @@ static const short libssh2_base64_reverse_table[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, @@ -123,42 +131,46 @@ static const short libssh2_base64_reverse_table[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; + /* }}} */ /* {{{ libssh2_base64_decode * 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) +LIBSSH2_API int +libssh2_base64_decode(LIBSSH2_SESSION * session, char **data, + unsigned int *datalen, const char *src, + unsigned int src_len) { unsigned char *s, *d; short v; int i = 0, len = 0; *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); - d = (unsigned char *)*data; + 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; + 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; + 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++; } @@ -171,22 +183,24 @@ LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, uns *datalen = len; return 0; } + /* }}} */ #ifdef LIBSSH2DEBUG -LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask) +LIBSSH2_API int +libssh2_trace(LIBSSH2_SESSION * session, int bitmask) { session->showmask = bitmask; return 0; } -void _libssh2_debug(LIBSSH2_SESSION *session, int context, - const char *format, ...) +void +_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...) { char buffer[1536]; int len; va_list vargs; - static const char * const contexts[9] = { + static const char *const contexts[9] = { "Unknown", "Transport", "Key Exchange", @@ -201,7 +215,7 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, if (context < 1 || context > 8) { context = 0; } - if (!(session->showmask & (1<showmask & (1 << context))) { /* no such output asked for */ return; } @@ -217,10 +231,11 @@ void _libssh2_debug(LIBSSH2_SESSION *session, int context, } #else -LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask) +LIBSSH2_API int +libssh2_trace(LIBSSH2_SESSION * session, int bitmask) { - (void)session; - (void)bitmask; + (void) session; + (void) bitmask; return 0; } #endif diff --git a/src/openssl.c b/src/openssl.c index dd2fba0..87e86dd 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -43,23 +43,23 @@ #define EVP_MAX_BLOCK_LENGTH 32 #endif -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) +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) { *rsa = RSA_new(); @@ -91,32 +91,32 @@ int _libssh2_rsa_new(libssh2_rsa_ctx **rsa, 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) +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) { 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); + (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) +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) { *dsactx = DSA_new(); @@ -140,10 +140,10 @@ int _libssh2_dsa_new(libssh2_dsa_ctx **dsactx, return 0; } -int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, - const unsigned char *sig, - const unsigned char *m, - unsigned long m_len) +int +_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len) { unsigned char hash[SHA_DIGEST_LENGTH]; DSA_SIG dsasig; @@ -162,27 +162,26 @@ int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx *dsactx, 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) +int +_libssh2_cipher_init(_libssh2_cipher_ctx * h, + _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; } -int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, - _libssh2_cipher_type(algo), - int encrypt, - unsigned char *block) +int +_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _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; + (void) algo; + (void) encrypt; if (blocksize == 1) { /* Hack for arcfour. */ @@ -199,11 +198,10 @@ int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, * calling program */ static int -passphrase_cb(char *buf, int size, - int rwflag, char *passphrase) +passphrase_cb(char *buf, int size, int rwflag, char *passphrase) { int passphrase_len = strlen(passphrase); - (void)rwflag; + (void) rwflag; if (passphrase_len > (size - 1)) { passphrase_len = size - 1; @@ -214,12 +212,12 @@ passphrase_cb(char *buf, int size, return passphrase_len; } -int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, - LIBSSH2_SESSION *session, - FILE *fp, - unsigned const char *passphrase) +int +_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + FILE * fp, unsigned const char *passphrase) { - (void)session; + (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 ($#&%#$(%$#( @@ -227,20 +225,20 @@ int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, */ OpenSSL_add_all_ciphers(); } - *rsa = PEM_read_RSAPrivateKey(fp, NULL, (void*)passphrase_cb, - (void*)passphrase); + *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) +int +_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + FILE * fp, unsigned const char *passphrase) { - (void)session; + (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 ($#&%#$(%$#( @@ -248,20 +246,20 @@ int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, */ OpenSSL_add_all_ciphers(); } - *dsa = PEM_read_DSAPrivateKey(fp, NULL, (void*)passphrase_cb, - (void*)passphrase); + *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) +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) { int ret; unsigned char *sig; @@ -287,14 +285,14 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, return 0; } -int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char *signature) +int +_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *signature) { DSA_SIG *sig; int r_len, s_len, rs_pad; - (void)hash_len; + (void) hash_len; sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); if (!sig) { diff --git a/src/openssl.h b/src/openssl.h index 7ed3446..cc7949b 100644 --- a/src/openssl.h +++ b/src/openssl.h @@ -131,66 +131,59 @@ #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); -int _libssh2_rsa_new_private (libssh2_rsa_ctx **rsa, - 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); -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); +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); +int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + 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); +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); #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); -int _libssh2_dsa_new_private (libssh2_dsa_ctx **dsa, - 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); -int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, - const unsigned char *hash, - unsigned long hash_len, - unsigned char *sig); +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); +int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + 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); +int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *sig); #define _libssh2_dsa_free(dsactx) DSA_free(dsactx) @@ -205,16 +198,14 @@ int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx *dsactx, #define _libssh2_cipher_cast5 EVP_cast5_cbc #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); +int _libssh2_cipher_init(_libssh2_cipher_ctx * h, + _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); +int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _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 1a2a36f..fd17186 100644 --- a/src/packet.c +++ b/src/packet.c @@ -61,10 +61,10 @@ /* {{{ libssh2_packet_queue_listener * Queue a connection request for a listener */ -static inline int -libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data, +static inline int +libssh2_packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data, unsigned long datalen, - packet_queue_listener_state_t *listen_state) + packet_queue_listener_state_t * listen_state) { /* * Look for a matching listener @@ -74,90 +74,108 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data, unsigned long packet_len = 17 + (sizeof(FwdNotReq) - 1); unsigned char *p; LIBSSH2_LISTENER *listen = session->listeners; - char failure_code = 1; /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */ + char failure_code = 1; /* SSH_OPEN_ADMINISTRATIVELY_PROHIBITED */ int rc; - - (void)datalen; - + + (void) datalen; + if (listen_state->state == libssh2_NB_state_idle) { - listen_state->sender_channel = libssh2_ntohu32(s); s += 4; - - listen_state->initial_window_size = libssh2_ntohu32(s); s += 4; - listen_state->packet_size = libssh2_ntohu32(s); s += 4; - - listen_state->host_len = libssh2_ntohu32(s); s += 4; - listen_state->host = s; s += listen_state->host_len; - listen_state->port = libssh2_ntohu32(s); s += 4; - - listen_state->shost_len = libssh2_ntohu32(s); s += 4; - listen_state->shost = s; s += listen_state->shost_len; - listen_state->sport = libssh2_ntohu32(s); s += 4; - + listen_state->sender_channel = libssh2_ntohu32(s); + s += 4; + + listen_state->initial_window_size = libssh2_ntohu32(s); + s += 4; + listen_state->packet_size = libssh2_ntohu32(s); + s += 4; + + listen_state->host_len = libssh2_ntohu32(s); + s += 4; + listen_state->host = s; + s += listen_state->host_len; + listen_state->port = libssh2_ntohu32(s); + s += 4; + + listen_state->shost_len = libssh2_ntohu32(s); + s += 4; + listen_state->shost = s; + s += listen_state->shost_len; + listen_state->sport = libssh2_ntohu32(s); + s += 4; + _libssh2_debug(session, LIBSSH2_DBG_CONN, "Remote received connection from %s:%ld to %s:%ld", listen_state->shost, listen_state->sport, listen_state->host, listen_state->port); - + listen_state->state = libssh2_NB_state_allocated; } - + if (listen_state->state != libssh2_NB_state_sent) { while (listen) { - if ((listen->port == (int)listen_state->port) && + if ((listen->port == (int) listen_state->port) && (strlen(listen->host) == listen_state->host_len) && - (memcmp(listen->host, listen_state->host, listen_state->host_len) == 0)) { + (memcmp + (listen->host, listen_state->host, + listen_state->host_len) == 0)) { /* This is our listener */ LIBSSH2_CHANNEL *channel, *last_queued = listen->queue; - + last_queued = listen->queue; if (listen_state->state == libssh2_NB_state_allocated) { if (listen->queue_maxsize && (listen->queue_maxsize <= listen->queue_size)) { /* Queue is full */ - failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ _libssh2_debug(session, LIBSSH2_DBG_CONN, "Listener queue full, ignoring"); listen_state->state = libssh2_NB_state_sent; 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 */ + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ listen_state->state = libssh2_NB_state_sent; 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); + 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 */ + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ listen_state->state = libssh2_NB_state_sent; break; } memcpy(channel->channel_type, "forwarded-tcpip", channel->channel_type_len + 1); - + channel->remote.id = listen_state->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->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 = listen_state->initial_window_size; - channel->local.window_size = listen_state->initial_window_size; + channel->local.window_size_initial = + listen_state->initial_window_size; + channel->local.window_size = + listen_state->initial_window_size; channel->local.packet_size = listen_state->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, @@ -165,7 +183,7 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data, channel->remote.window_size, channel->local.packet_size, channel->remote.packet_size); - + p = listen_state->packet; *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; libssh2_htonu32(p, channel->remote.id); @@ -176,52 +194,51 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data, p += 4; libssh2_htonu32(p, channel->remote.packet_size); p += 4; - + listen_state->state = libssh2_NB_state_created; } - + if (listen_state->state == libssh2_NB_state_created) { rc = libssh2_packet_write(session, listen_state->packet, 17); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel open confirmation", 0); listen_state->state = libssh2_NB_state_idle; return -1; } - + /* Link the channel into the end of the queue list */ - + if (!last_queued) { listen->queue = channel; listen_state->state = libssh2_NB_state_idle; return 0; } - + while (last_queued->next) { last_queued = last_queued->next; } - + last_queued->next = channel; channel->prev = last_queued; - + listen->queue_size++; - + listen_state->state = libssh2_NB_state_idle; return 0; } } - + listen = listen->next; } - + listen_state->state = libssh2_NB_state_sent; } - + /* We're not listening to you */ { p = listen_state->packet; @@ -235,12 +252,11 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data, memcpy(s, FwdNotReq, sizeof(FwdNotReq) - 1); p += sizeof(FwdNotReq) - 1; libssh2_htonu32(p, 0); - + rc = libssh2_packet_write(session, listen_state->packet, packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send open failure", 0); listen_state->state = libssh2_NB_state_idle; @@ -250,42 +266,49 @@ libssh2_packet_queue_listener(LIBSSH2_SESSION *session, unsigned char *data, return 0; } } + /* }}} */ /* {{{ libssh2_packet_x11_open * Accept a forwarded X11 connection */ -static inline int -libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data, +static inline int +libssh2_packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data, unsigned long datalen, - packet_x11_open_state_t *x11open_state) + packet_x11_open_state_t * x11open_state) { - int failure_code = 2; /* SSH_OPEN_CONNECT_FAILED */ + int failure_code = 2; /* SSH_OPEN_CONNECT_FAILED */ unsigned char *s = data + (sizeof("x11") - 1) + 5; /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1); unsigned char *p; LIBSSH2_CHANNEL *channel; int rc; - - (void)datalen; - + + (void) datalen; + if (x11open_state->state == libssh2_NB_state_idle) { - x11open_state->sender_channel = libssh2_ntohu32(s); s += 4; - x11open_state->initial_window_size = libssh2_ntohu32(s); s += 4; - x11open_state->packet_size = libssh2_ntohu32(s); s += 4; - x11open_state->shost_len = libssh2_ntohu32(s); s += 4; - x11open_state->shost = s; s += x11open_state->shost_len; - x11open_state->sport = libssh2_ntohu32(s); s += 4; - + x11open_state->sender_channel = libssh2_ntohu32(s); + s += 4; + x11open_state->initial_window_size = libssh2_ntohu32(s); + s += 4; + x11open_state->packet_size = libssh2_ntohu32(s); + s += 4; + x11open_state->shost_len = libssh2_ntohu32(s); + s += 4; + x11open_state->shost = s; + s += x11open_state->shost_len; + x11open_state->sport = libssh2_ntohu32(s); + s += 4; + _libssh2_debug(session, LIBSSH2_DBG_CONN, "X11 Connection Received from %s:%ld on channel %lu", x11open_state->shost, x11open_state->sport, x11open_state->sender_channel); - + x11open_state->state = libssh2_NB_state_allocated; } - + if (session->x11) { if (x11open_state->state == libssh2_NB_state_allocated) { channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL)); @@ -293,35 +316,39 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data, libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a channel for new connection", 0); - failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ + 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); + 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 */ + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ goto x11_exit; } - memcpy(channel->channel_type, "x11", channel->channel_type_len + 1); - + memcpy(channel->channel_type, "x11", + channel->channel_type_len + 1); + channel->remote.id = x11open_state->sender_channel; - channel->remote.window_size_initial = LIBSSH2_CHANNEL_WINDOW_DEFAULT; + 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 = x11open_state->initial_window_size; + channel->local.window_size_initial = + x11open_state->initial_window_size; channel->local.window_size = x11open_state->initial_window_size; channel->local.packet_size = x11open_state->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, @@ -331,26 +358,29 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data, channel->remote.packet_size); p = x11open_state->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; - + 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; + x11open_state->state = libssh2_NB_state_created; } - + if (x11open_state->state == libssh2_NB_state_created) { rc = libssh2_packet_write(session, x11open_state->packet, 17); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send channel open confirmation", 0); x11open_state->state = libssh2_NB_state_idle; return -1; } - + /* Link the channel into the session */ if (session->channels.tail) { session->channels.tail->next = channel; @@ -361,35 +391,38 @@ libssh2_packet_x11_open(LIBSSH2_SESSION *session, unsigned char *data, } 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 *)x11open_state->shost, x11open_state->sport); - + LIBSSH2_X11_OPEN(channel, (char *) x11open_state->shost, + x11open_state->sport); + x11open_state->state = libssh2_NB_state_idle; return 0; } } else { - failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ + failure_code = 4; /* SSH_OPEN_RESOURCE_SHORTAGE */ } - -x11_exit: + + x11_exit: p = x11open_state->packet; *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; - libssh2_htonu32(p, x11open_state->sender_channel); p += 4; - libssh2_htonu32(p, failure_code); p += 4; - libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1); p += 4; + libssh2_htonu32(p, x11open_state->sender_channel); + p += 4; + libssh2_htonu32(p, failure_code); + p += 4; + libssh2_htonu32(p, sizeof(X11FwdUnAvil) - 1); + p += 4; memcpy(s, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1); - p += sizeof(X11FwdUnAvil) - 1; + p += sizeof(X11FwdUnAvil) - 1; libssh2_htonu32(p, 0); - + rc = libssh2_packet_write(session, x11open_state->packet, packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send open failure", 0); x11open_state->state = libssh2_NB_state_idle; @@ -398,37 +431,39 @@ x11_exit: x11open_state->state = libssh2_NB_state_idle; return 0; } + /* }}} */ /* {{{ libssh2_packet_new * Create a new packet and attach it to the brigade */ -int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, - size_t datalen, int macstate) +int +libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, + size_t datalen, int macstate) { int rc; - + if (session->packAdd_state == libssh2_NB_state_idle) { session->packAdd_data_head = 0; - + /* Zero the whole thing out */ memset(&session->packAdd_key_state, 0, sizeof(session->packAdd_key_state)); - + /* Zero the whole thing out */ memset(&session->packAdd_Qlstn_state, 0, sizeof(session->packAdd_Qlstn_state)); - + /* Zero the whole thing out */ memset(&session->packAdd_x11open_state, 0, sizeof(session->packAdd_x11open_state)); - + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Packet type %d received, length=%d", - (int)data[0], (int)datalen); + (int) data[0], (int) datalen); if (macstate == LIBSSH2_MAC_INVALID) { if (session->macerror) { - if (LIBSSH2_MACERROR(session, (char *)data, datalen) == 0) { + if (LIBSSH2_MACERROR(session, (char *) data, datalen) == 0) { /* Calling app has given the OK, Process it anyway */ macstate = LIBSSH2_MAC_CONFIRMED; } else { @@ -458,7 +493,7 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, return -1; } } - + session->packAdd_state = libssh2_NB_state_allocated; } @@ -469,351 +504,374 @@ int libssh2_packet_add(LIBSSH2_SESSION *session, unsigned char *data, */ if (session->packAdd_state == libssh2_NB_state_jump1) { goto libssh2_packet_add_jump_point1; - } - else if (session->packAdd_state == libssh2_NB_state_jump2) { + } else if (session->packAdd_state == libssh2_NB_state_jump2) { goto libssh2_packet_add_jump_point2; - } - else if (session->packAdd_state == libssh2_NB_state_jump3) { + } else if (session->packAdd_state == libssh2_NB_state_jump3) { goto libssh2_packet_add_jump_point3; } - + if (session->packAdd_state == libssh2_NB_state_allocated) { /* 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); - /* 9 = packet_type(1) + reason(4) + message_len(4) */ - message = (char *)data + 9; - 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; - session->packAdd_state = libssh2_NB_state_idle; - return -1; + case SSH_MSG_DISCONNECT: + { + char *message, *language; + int reason, message_len, language_len; + + reason = libssh2_ntohu32(data + 1); + message_len = libssh2_ntohu32(data + 5); + /* 9 = packet_type(1) + reason(4) + message_len(4) */ + message = (char *) data + 9; + 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); } - 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); + 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; + session->packAdd_state = libssh2_NB_state_idle; + 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); + session->packAdd_state = libssh2_NB_state_idle; + 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); + /* 6 = packet_type(1) + display(1) + message_len(4) */ + message = (char *) data + 6; + 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); session->packAdd_state = libssh2_NB_state_idle; 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); - /* 6 = packet_type(1) + display(1) + message_len(4) */ - message = (char *)data + 6; - 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); + } + break; + + case SSH_MSG_CHANNEL_EXTENDED_DATA: + /* streamid(4) */ + session->packAdd_data_head += 4; + case SSH_MSG_CHANNEL_DATA: + /* packet_type(1) + channelno(4) + datalen(4) */ + session->packAdd_data_head += 9; + { + session->packAdd_channel = libssh2_channel_locate(session, + libssh2_ntohu32 + (data + 1)); + + if (!session->packAdd_channel) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, + "Packet received for unknown channel, ignoring", + 0); LIBSSH2_FREE(session, data); session->packAdd_state = libssh2_NB_state_idle; return 0; } - break; - - case SSH_MSG_CHANNEL_EXTENDED_DATA: - /* streamid(4) */ - session->packAdd_data_head += 4; - case SSH_MSG_CHANNEL_DATA: - /* packet_type(1) + channelno(4) + datalen(4) */ - session->packAdd_data_head += 9; - { - session->packAdd_channel = libssh2_channel_locate(session, - libssh2_ntohu32(data + 1)); - - if (!session->packAdd_channel) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, - "Packet received for unknown channel, ignoring", - 0); - LIBSSH2_FREE(session, data); - session->packAdd_state = libssh2_NB_state_idle; - 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 - session->packAdd_data_head), - session->packAdd_channel->local.id, - session->packAdd_channel->remote.id, - stream_id); - } -#endif - if ((session->packAdd_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_packet_add_jump_point1: - session->packAdd_state = libssh2_NB_state_jump1; - rc = libssh2_channel_receive_window_adjust(session->packAdd_channel, - datalen - 13, 0); - if (rc == PACKET_EAGAIN) { - return PACKET_EAGAIN; - } - session->packAdd_state = libssh2_NB_state_idle; - return 0; - } - - /* - * REMEMBER! remote means remote as source of data, - * NOT remote window! - */ - if (session->packAdd_channel->remote.packet_size < (datalen - session->packAdd_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 = session->packAdd_channel->remote.packet_size + session->packAdd_data_head; - } - if (session->packAdd_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); - session->packAdd_state = libssh2_NB_state_idle; - return 0; - } - /* Reset EOF status */ - session->packAdd_channel->remote.eof = 0; - - if ((datalen - session->packAdd_data_head) > session->packAdd_channel->remote.window_size) { - libssh2_error(session, - LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, - "Remote sent more data than current window allows, truncating", - 0); - datalen = session->packAdd_channel->remote.window_size + session->packAdd_data_head; - } else { - /* Now that we've received it, shrink our window */ - session->packAdd_channel->remote.window_size -= datalen - session->packAdd_data_head; - } - } - break; - - case SSH_MSG_CHANNEL_EOF: { - session->packAdd_channel = libssh2_channel_locate(session, - libssh2_ntohu32(data + 1)); - - if (!session->packAdd_channel) { - /* We may have freed already, just quietly ignore this... */ - LIBSSH2_FREE(session, data); - session->packAdd_state = libssh2_NB_state_idle; - return 0; - } - - _libssh2_debug(session, - LIBSSH2_DBG_CONN, - "EOF received for channel %lu/%lu", - session->packAdd_channel->local.id, - session->packAdd_channel->remote.id); - session->packAdd_channel->remote.eof = 1; - - LIBSSH2_FREE(session, data); - session->packAdd_state = libssh2_NB_state_idle; - 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 */ - session->packAdd_channel = libssh2_channel_locate(session, libssh2_ntohu32(data+1)); - - if (session->packAdd_channel) { - session->packAdd_channel->exit_status = libssh2_ntohu32(data + 9 + sizeof("exit-status")); - _libssh2_debug(session, LIBSSH2_DBG_CONN, - "Exit status %lu received for channel %lu/%lu", - session->packAdd_channel->exit_status, - session->packAdd_channel->local.id, - session->packAdd_channel->remote.id); - } - - LIBSSH2_FREE(session, data); - session->packAdd_state = libssh2_NB_state_idle; - return 0; - } - } - break; - - case SSH_MSG_CHANNEL_CLOSE: - { - session->packAdd_channel = libssh2_channel_locate(session, - libssh2_ntohu32(data + 1)); - - if (!session->packAdd_channel) { - /* We may have freed already, just quietly ignore this... */ - LIBSSH2_FREE(session, data); - session->packAdd_state = libssh2_NB_state_idle; - return 0; + 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, - "Close received for channel %lu/%lu", - session->packAdd_channel->local.id, - session->packAdd_channel->remote.id); - - session->packAdd_channel->remote.close = 1; - session->packAdd_channel->remote.eof = 1; - /* TODO: Add a callback for this */ - - LIBSSH2_FREE(session, data); - session->packAdd_state = libssh2_NB_state_idle; - 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)) { - -libssh2_packet_add_jump_point2: - session->packAdd_state = libssh2_NB_state_jump2; - rc = libssh2_packet_queue_listener(session, data, datalen, - &session->packAdd_Qlstn_state); - if (rc == PACKET_EAGAIN) { - return PACKET_EAGAIN; - } - - LIBSSH2_FREE(session, data); - session->packAdd_state = libssh2_NB_state_idle; - return rc; - } - if ((datalen >= (sizeof("x11") + 4)) && - ((sizeof("x11")-1) == libssh2_ntohu32(data + 1)) && - (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) { - -libssh2_packet_add_jump_point3: - session->packAdd_state = libssh2_NB_state_jump3; - rc = libssh2_packet_x11_open(session, data, datalen, - &session->packAdd_x11open_state); - if (rc == PACKET_EAGAIN) { - return PACKET_EAGAIN; - } - - LIBSSH2_FREE(session, data); - session->packAdd_state = libssh2_NB_state_idle; - return rc; - } - break; - - case SSH_MSG_CHANNEL_WINDOW_ADJUST: - { - unsigned long bytestoadd = libssh2_ntohu32(data + 5); - session->packAdd_channel = libssh2_channel_locate(session, - libssh2_ntohu32(data + 1)); - - if (session->packAdd_channel && bytestoadd) { - session->packAdd_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", + "%d bytes received for channel %lu/%lu stream #%lu", + (int) (datalen - + session->packAdd_data_head), session->packAdd_channel->local.id, session->packAdd_channel->remote.id, - bytestoadd, - session->packAdd_channel->local.window_size); - + stream_id); + } +#endif + if ((session->packAdd_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_packet_add_jump_point1: + session->packAdd_state = libssh2_NB_state_jump1; + rc = libssh2_channel_receive_window_adjust(session-> + packAdd_channel, + datalen - 13, + 0); + if (rc == PACKET_EAGAIN) { + return PACKET_EAGAIN; + } + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + + /* + * REMEMBER! remote means remote as source of data, + * NOT remote window! + */ + if (session->packAdd_channel->remote.packet_size < + (datalen - session->packAdd_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 = + session->packAdd_channel->remote.packet_size + + session->packAdd_data_head; + } + if (session->packAdd_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); session->packAdd_state = libssh2_NB_state_idle; return 0; } - break; + /* Reset EOF status */ + session->packAdd_channel->remote.eof = 0; + + if ((datalen - session->packAdd_data_head) > + session->packAdd_channel->remote.window_size) { + libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, + "Remote sent more data than current window allows, truncating", + 0); + datalen = + session->packAdd_channel->remote.window_size + + session->packAdd_data_head; + } else { + /* Now that we've received it, shrink our window */ + session->packAdd_channel->remote.window_size -= + datalen - session->packAdd_data_head; + } + } + break; + + case SSH_MSG_CHANNEL_EOF: + { + session->packAdd_channel = libssh2_channel_locate(session, + libssh2_ntohu32 + (data + 1)); + + if (!session->packAdd_channel) { + /* We may have freed already, just quietly ignore this... */ + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + + _libssh2_debug(session, + LIBSSH2_DBG_CONN, + "EOF received for channel %lu/%lu", + session->packAdd_channel->local.id, + session->packAdd_channel->remote.id); + session->packAdd_channel->remote.eof = 1; + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + 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 */ + session->packAdd_channel = + libssh2_channel_locate(session, + libssh2_ntohu32(data + 1)); + + if (session->packAdd_channel) { + session->packAdd_channel->exit_status = + libssh2_ntohu32(data + 9 + sizeof("exit-status")); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Exit status %lu received for channel %lu/%lu", + session->packAdd_channel->exit_status, + session->packAdd_channel->local.id, + session->packAdd_channel->remote.id); + } + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + } + break; + + case SSH_MSG_CHANNEL_CLOSE: + { + session->packAdd_channel = libssh2_channel_locate(session, + libssh2_ntohu32 + (data + 1)); + + if (!session->packAdd_channel) { + /* We may have freed already, just quietly ignore this... */ + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Close received for channel %lu/%lu", + session->packAdd_channel->local.id, + session->packAdd_channel->remote.id); + + session->packAdd_channel->remote.close = 1; + session->packAdd_channel->remote.eof = 1; + /* TODO: Add a callback for this */ + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + 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)) { + + libssh2_packet_add_jump_point2: + session->packAdd_state = libssh2_NB_state_jump2; + rc = libssh2_packet_queue_listener(session, data, datalen, + &session-> + packAdd_Qlstn_state); + if (rc == PACKET_EAGAIN) { + return PACKET_EAGAIN; + } + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return rc; + } + if ((datalen >= (sizeof("x11") + 4)) && + ((sizeof("x11") - 1) == libssh2_ntohu32(data + 1)) && + (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) { + + libssh2_packet_add_jump_point3: + session->packAdd_state = libssh2_NB_state_jump3; + rc = libssh2_packet_x11_open(session, data, datalen, + &session->packAdd_x11open_state); + if (rc == PACKET_EAGAIN) { + return PACKET_EAGAIN; + } + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return rc; + } + break; + + case SSH_MSG_CHANNEL_WINDOW_ADJUST: + { + unsigned long bytestoadd = libssh2_ntohu32(data + 5); + session->packAdd_channel = libssh2_channel_locate(session, + libssh2_ntohu32 + (data + 1)); + + if (session->packAdd_channel && bytestoadd) { + session->packAdd_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", + session->packAdd_channel->local.id, + session->packAdd_channel->remote.id, + bytestoadd, + session->packAdd_channel->local.window_size); + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + break; } - + session->packAdd_state = libssh2_NB_state_sent; } - + if (session->packAdd_state == libssh2_NB_state_sent) { - session->packAdd_packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); + session->packAdd_packet = + LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); if (!session->packAdd_packet) { _libssh2_debug(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for LIBSSH2_PACKET"); @@ -822,14 +880,14 @@ libssh2_packet_add_jump_point3: return -1; } memset(session->packAdd_packet, 0, sizeof(LIBSSH2_PACKET)); - + session->packAdd_packet->data = data; session->packAdd_packet->data_len = datalen; session->packAdd_packet->data_head = session->packAdd_data_head; session->packAdd_packet->mac = macstate; session->packAdd_packet->brigade = &session->packets; session->packAdd_packet->next = NULL; - + if (session->packets.tail) { session->packAdd_packet->prev = session->packets.tail; session->packAdd_packet->prev->next = session->packAdd_packet; @@ -839,10 +897,10 @@ libssh2_packet_add_jump_point3: session->packets.tail = session->packAdd_packet; session->packAdd_packet->prev = NULL; } - + session->packAdd_state = libssh2_NB_state_sent1; } - + if ((data[0] == SSH_MSG_KEXINIT && !(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) || (session->packAdd_state == libssh2_NB_state_sent2)) { @@ -853,7 +911,7 @@ libssh2_packet_add_jump_point3: * let's just call back into ourselves */ _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Renegotiating Keys"); - + session->packAdd_state = libssh2_NB_state_sent2; } /* @@ -865,21 +923,25 @@ libssh2_packet_add_jump_point3: return PACKET_EAGAIN; } } - + session->packAdd_state = libssh2_NB_state_idle; return 0; } + /* }}} */ /* {{{ libssh2_packet_ask * Scan the brigade for a matching packet type, optionally poll the socket for * a packet first */ -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) +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) { LIBSSH2_PACKET *packet = session->packets.head; - + if (poll_socket) { /* * XXX CHECK *** @@ -893,49 +955,59 @@ int libssh2_packet_ask_ex(LIBSSH2_SESSION *session, unsigned char packet_type, u } } _libssh2_debug(session, LIBSSH2_DBG_TRANS, - "Looking for packet of type: %d", (int)packet_type); - + "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))) { + 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; } return -1; } + /* }}} */ /* {{{ libssh2_packet_askv * Scan for any of a list of packet types in the brigade, optionally poll the * socket for a packet first */ -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) +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) { - int i, packet_types_len = strlen((char *)packet_types); - + int i, packet_types_len = strlen((char *) packet_types); + for(i = 0; i < packet_types_len; i++) { /* * XXX CHECK XXX @@ -943,15 +1015,16 @@ int libssh2_packet_askv_ex(LIBSSH2_SESSION *session, * return PACKET_EAGAIN. Not sure the correct action, I * think it is right as is. */ - if (0 == libssh2_packet_ask_ex(session, packet_types[i], data, - data_len, match_ofs, match_buf, + 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; } + /* }}} */ /* {{{ waitsocket @@ -962,7 +1035,8 @@ 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) +int +libssh2_waitsocket(LIBSSH2_SESSION * session, long seconds) { struct timeval timeout; int rc; @@ -975,7 +1049,7 @@ int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds) FD_SET(session->socket_fd, &fd); - rc = select(session->socket_fd+1, &fd, NULL, NULL, &timeout); + rc = select(session->socket_fd + 1, &fd, NULL, NULL, &timeout); return rc; } @@ -987,55 +1061,62 @@ int libssh2_waitsocket(LIBSSH2_SESSION *session, long seconds) * Returns negative on error * Returns 0 when it has taken care of the requested packet. */ -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, packet_require_state_t *state) +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, + packet_require_state_t * state) { if (state->start == 0) { - if (libssh2_packet_ask_ex(session, packet_type, data, data_len, match_ofs, match_buf, match_len, 0) == 0) { + 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; } - + state->start = time(NULL); - - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "May block until packet of type %d becomes available", (int)packet_type); + + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "May block 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 == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if ((ret == 0) && (!session->socket_block)) { + } else if ((ret == 0) && (!session->socket_block)) { /* If we are in non-blocking and there is no data, return that */ return PACKET_EAGAIN; - } - else if (ret < 0) { + } else if (ret < 0) { state->start = 0; /* an error which is not just because of blocking */ return ret; - } - else if (ret == packet_type) { + } else if (ret == packet_type) { /* 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); + ret = + libssh2_packet_ask_ex(session, packet_type, data, data_len, + match_ofs, match_buf, match_len, 0); state->start = 0; return ret; - } - else if (ret == 0) { + } else if (ret == 0) { /* nothing available, wait until data arrives or we time out */ long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start); - + if ((left <= 0) || (libssh2_waitsocket(session, left) <= 0)) { state->start = 0; return PACKET_TIMEOUT; } } } - + /* Only reached if the socket died */ return -1; } + /* }}} */ /* {{{ libssh2_packet_burn @@ -1043,55 +1124,60 @@ int libssh2_packet_require_ex(LIBSSH2_SESSION *session, unsigned char packet_typ * discards it * Used during KEX exchange to discard badly guessed KEX_INIT packets */ -int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *state) +int +libssh2_packet_burn(LIBSSH2_SESSION * session, + libssh2_nonblocking_states * state) { unsigned char *data; unsigned long data_len; unsigned char all_packets[255]; int i; int ret; - + if (*state == libssh2_NB_state_idle) { 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) { + + 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"); + + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "Blocking until packet becomes available to burn"); *state = libssh2_NB_state_created; } - + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { if ((ret = libssh2_packet_read(session)) == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (ret < 0) { + } else if (ret < 0) { *state = libssh2_NB_state_idle; return ret; - } - else if (ret == 0) { + } else 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)) { + 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); *state = libssh2_NB_state_idle; return ret; } } - + /* Only reached if the socket died */ return -1; } + /* }}} */ /* @@ -1103,21 +1189,28 @@ int libssh2_packet_burn(LIBSSH2_SESSION *session, libssh2_nonblocking_states *st * packet_types is a null terminated list of packet_type numbers */ -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, packet_requirev_state_t *state) +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, + packet_requirev_state_t * state) { - if (libssh2_packet_askv_ex(session, packet_types, data, data_len, match_ofs, match_buf, match_len, 0) == 0) { + 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 */ state->start = 0; return 0; } - + if (state->start == 0) { state->start = time(NULL); } - + while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) { int ret = libssh2_packet_read(session); if ((ret < 0) && (ret != PACKET_EAGAIN)) { @@ -1126,24 +1219,26 @@ int libssh2_packet_requirev_ex(LIBSSH2_SESSION *session, const unsigned char *pa } if (ret <= 0) { long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - state->start); - - if ((left <= 0) || (libssh2_waitsocket(session, left) <= 0 )) { + + if ((left <= 0) || (libssh2_waitsocket(session, left) <= 0)) { state->start = 0; return PACKET_TIMEOUT; - } - else if (ret == PACKET_EAGAIN) { + } else if (ret == PACKET_EAGAIN) { return PACKET_EAGAIN; } } - - if (strchr((char *)packet_types, ret)) { + + 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); + return libssh2_packet_askv_ex(session, packet_types, data, + data_len, match_ofs, match_buf, + match_len, 0); } } - + /* Only reached if the socket died */ state->start = 0; return -1; } + /* }}} */ diff --git a/src/pem.c b/src/pem.c index 875f6aa..58c01e8 100644 --- a/src/pem.c +++ b/src/pem.c @@ -37,18 +37,16 @@ #include "libssh2_priv.h" -static int readline (char *line, int line_size, FILE *fp) +static int +readline(char *line, int line_size, FILE * fp) { - if (!fgets(line, line_size, fp)) - { + if (!fgets(line, line_size, fp)) { return -1; } - if (*line && line[strlen(line) - 1] == '\n') - { + if (*line && line[strlen(line) - 1] == '\n') { line[strlen(line) - 1] = '\0'; } - if (*line && line[strlen(line) - 1] == '\r') - { + if (*line && line[strlen(line) - 1] == '\r') { line[strlen(line) - 1] = '\0'; } return 0; @@ -56,132 +54,114 @@ static int readline (char *line, int line_size, FILE *fp) #define LINE_SIZE 128 -int _libssh2_pem_parse (LIBSSH2_SESSION *session, - const char *headerbegin, - const char *headerend, - FILE *fp, - char **data, unsigned int *datalen) +int +_libssh2_pem_parse(LIBSSH2_SESSION * session, + 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; - do - { - if (readline(line, LINE_SIZE, fp)) - { + do { + if (readline(line, LINE_SIZE, fp)) { return -1; } } - while (strcmp (line, headerbegin) != 0); + while (strcmp(line, headerbegin) != 0); *line = '\0'; - do - { - if (*line) - { + do { + if (*line) { char *tmp; size_t linelen; - linelen = strlen (line); - tmp = LIBSSH2_REALLOC (session, b64data, - b64datalen + linelen); - if (!tmp) - { + linelen = strlen(line); + tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); + if (!tmp) { ret = -1; goto out; } - memcpy (tmp + b64datalen, line, linelen); + memcpy(tmp + b64datalen, line, linelen); b64data = tmp; b64datalen += linelen; } - if (readline(line, LINE_SIZE, fp)) - { + if (readline(line, LINE_SIZE, fp)) { ret = -1; goto out; } - } while (strcmp (line, headerend) != 0); + } while (strcmp(line, headerend) != 0); - if (libssh2_base64_decode(session, data, datalen, - b64data, b64datalen)) - { + if (libssh2_base64_decode(session, data, datalen, b64data, b64datalen)) { ret = -1; goto out; } ret = 0; -out: + out: if (b64data) { - LIBSSH2_FREE (session, b64data); + LIBSSH2_FREE(session, b64data); } return ret; } -static int read_asn1_length (const unsigned char *data, - unsigned int datalen, - unsigned int *len) +static int +read_asn1_length(const unsigned char *data, + unsigned int datalen, unsigned int *len) { unsigned int lenlen; int nextpos; - if (datalen < 1) - { + if (datalen < 1) { return -1; } *len = data[0]; - if (*len >= 0x80) - { + if (*len >= 0x80) { lenlen = *len & 0x7F; *len = data[1]; - if (1 + lenlen > datalen) - { + if (1 + lenlen > datalen) { return -1; } - if (lenlen > 1) - { + if (lenlen > 1) { *len <<= 8; *len |= data[2]; } - } - else - { + } else { lenlen = 0; } nextpos = 1 + lenlen; - if (lenlen > 2 || 1 + lenlen + *len > datalen) - { + if (lenlen > 2 || 1 + lenlen + *len > datalen) { return -1; } return nextpos; } -int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen) +int +_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen) { unsigned int len; int lenlen; - if (*datalen < 1) - { + if (*datalen < 1) { return -1; } - if ((*data)[0] != '\x30') - { + if ((*data)[0] != '\x30') { return -1; } (*data)++; (*datalen)--; - lenlen = read_asn1_length (*data, *datalen, &len); - if (lenlen < 0 || lenlen + len != *datalen) - { + lenlen = read_asn1_length(*data, *datalen, &len); + if (lenlen < 0 || lenlen + len != *datalen) { return -1; } @@ -191,28 +171,26 @@ int _libssh2_pem_decode_sequence (unsigned char **data, unsigned int *datalen) return 0; } -int _libssh2_pem_decode_integer (unsigned char **data, unsigned int *datalen, - unsigned char **i, unsigned int *ilen) +int +_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen, + unsigned char **i, unsigned int *ilen) { unsigned int len; int lenlen; - if (*datalen < 1) - { + if (*datalen < 1) { return -1; } - if ((*data)[0] != '\x02') - { + if ((*data)[0] != '\x02') { return -1; } (*data)++; (*datalen)--; - lenlen = read_asn1_length (*data, *datalen, &len); - if (lenlen < 0 || lenlen + len > *datalen) - { + lenlen = read_asn1_length(*data, *datalen, &len); + if (lenlen < 0 || lenlen + len > *datalen) { return -1; } diff --git a/src/publickey.c b/src/publickey.c index 6eda6c3..311d2d9 100644 --- a/src/publickey.c +++ b/src/publickey.c @@ -45,17 +45,21 @@ #define LIBSSH2_PUBLICKEY_RESPONSE_VERSION 1 #define LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY 2 -typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST { +typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST +{ 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 */ @@ -72,16 +76,33 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_response_codes[] = { #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 @@ -91,7 +112,8 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST libssh2_publickey_status_codes[] = { #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, +libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY * pkey, + LIBSSH2_SESSION * session, int status, const unsigned char *message, int message_len) { const char *status_text; @@ -112,32 +134,41 @@ libssh2_publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, LIBSSH2_SESSION *s 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_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); + 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); + 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); } + /* }}} */ /* {{{ libssh2_publickey_packet_receive * Read a packet from the subsystem */ static int -libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data, unsigned long *data_len) +libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey, + unsigned char **data, unsigned long *data_len) { LIBSSH2_CHANNEL *channel = pkey->channel; LIBSSH2_SESSION *session = channel->session; @@ -145,32 +176,36 @@ libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data, int rc; if (pkey->receive_state == libssh2_NB_state_idle) { - rc = libssh2_channel_read_ex(channel, 0, (char *)buffer, 4); + rc = libssh2_channel_read_ex(channel, 0, (char *) buffer, 4); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc != 4) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid response from publickey subsystem", 0); + } else if (rc != 4) { + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid response from publickey subsystem", 0); return -1; } pkey->receive_packet_len = libssh2_ntohu32(buffer); - pkey->receive_packet = LIBSSH2_ALLOC(session, pkey->receive_packet_len); + pkey->receive_packet = + LIBSSH2_ALLOC(session, pkey->receive_packet_len); if (!pkey->receive_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate publickey response buffer", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate publickey response buffer", 0); return -1; } - + pkey->receive_state = libssh2_NB_state_sent; } if (pkey->receive_state == libssh2_NB_state_sent) { - rc = libssh2_channel_read_ex(channel, 0, (char *)pkey->receive_packet, pkey->receive_packet_len); + rc = libssh2_channel_read_ex(channel, 0, (char *) pkey->receive_packet, + pkey->receive_packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc != pkey->receive_packet_len) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for publickey subsystem response packet", 0); + } else if (rc != pkey->receive_packet_len) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for publickey subsystem response packet", + 0); LIBSSH2_FREE(session, pkey->receive_packet); pkey->receive_packet = NULL; pkey->receive_state = libssh2_NB_state_idle; @@ -180,28 +215,33 @@ libssh2_publickey_packet_receive(LIBSSH2_PUBLICKEY *pkey, unsigned char **data, *data = pkey->receive_packet; *data_len = pkey->receive_packet_len; } - + pkey->receive_state = libssh2_NB_state_idle; return 0; } + /* }}} */ /* {{{ libssh2_publickey_response_id * Translate a string response name to a numeric code * Data will be incremented by 4 + response_len on success only */ -static int libssh2_publickey_response_id(unsigned char **pdata, int data_len) +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; + 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; + response_len = libssh2_ntohu32(data); + data += 4; + data_len -= 4; if (data_len < response_len) { /* Malformed response */ return -1; @@ -209,7 +249,7 @@ static int libssh2_publickey_response_id(unsigned char **pdata, int data_len) while (codes->name) { if (codes->name_len == response_len && - strncmp(codes->name, (char *)data, response_len) == 0) { + strncmp(codes->name, (char *) data, response_len) == 0) { *pdata = data + response_len; return codes->code; } @@ -218,12 +258,14 @@ static int libssh2_publickey_response_id(unsigned char **pdata, int data_len) return -1; } + /* }}} */ /* {{{ libssh2_publickey_response_success * Generic helper routine to wait for success response and nothing else */ -static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey) +static int +libssh2_publickey_response_success(LIBSSH2_PUBLICKEY * pkey) { LIBSSH2_SESSION *session = pkey->channel->session; unsigned char *data, *s; @@ -235,34 +277,42 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey) rc = libssh2_publickey_packet_receive(pkey, &data, &data_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0); + } else if (rc) { + 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_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: + 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; + + 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_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Malformed publickey subsystem packet", 0); LIBSSH2_FREE(session, data); return -1; } @@ -272,20 +322,24 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey) return 0; } - libssh2_publickey_status_error(pkey, session, status, descr, descr_len); + 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; + 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; } + /* }}} */ @@ -296,7 +350,8 @@ static int libssh2_publickey_response_success(LIBSSH2_PUBLICKEY *pkey) /* {{{ libssh2_publickey_init * Startup the publickey subsystem */ -LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session) +LIBSSH2_API LIBSSH2_PUBLICKEY * +libssh2_publickey_init(LIBSSH2_SESSION * session) { /* 19 = packet_len(4) + version_len(4) + "version"(7) + version_num(4) */ unsigned char buffer[19]; @@ -308,56 +363,72 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session) session->pkeyInit_data = NULL; session->pkeyInit_pkey = NULL; session->pkeyInit_channel = NULL; - - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Initializing publickey subsystem"); - + + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, + "Initializing publickey subsystem"); + session->pkeyInit_state = libssh2_NB_state_allocated; } if (session->pkeyInit_state == libssh2_NB_state_allocated) { do { - session->pkeyInit_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1, - LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, - NULL, 0); - if (!session->pkeyInit_channel && (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN)) { + session->pkeyInit_channel = + libssh2_channel_open_ex(session, "session", + sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, + 0); + if (!session->pkeyInit_channel + && (libssh2_session_last_errno(session) == + LIBSSH2_ERROR_EAGAIN)) { /* The error state is already set, so leave it */ - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block to startup channel", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block to startup channel", 0); return NULL; - } - else if (!session->pkeyInit_channel && (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN)) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to startup channel", 0); + } else if (!session->pkeyInit_channel + && (libssh2_session_last_errno(session) != + LIBSSH2_ERROR_EAGAIN)) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to startup channel", 0); goto err_exit; } } while (!session->pkeyInit_channel); - + session->pkeyInit_state = libssh2_NB_state_sent; } - + if (session->pkeyInit_state == libssh2_NB_state_sent) { - rc = libssh2_channel_process_startup(session->pkeyInit_channel, "subsystem", sizeof("subsystem") - 1, + rc = libssh2_channel_process_startup(session->pkeyInit_channel, + "subsystem", + sizeof("subsystem") - 1, "publickey", strlen("publickey")); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting publickkey subsystem", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting publickkey subsystem", 0); return NULL; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to request publickey subsystem", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to request publickey subsystem", 0); goto err_exit; } - + session->pkeyInit_state = libssh2_NB_state_sent1; } if (session->pkeyInit_state == libssh2_NB_state_sent1) { - rc = libssh2_channel_handle_extended_data2(session->pkeyInit_channel, LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); + rc = libssh2_channel_handle_extended_data2(session->pkeyInit_channel, + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting publickkey subsystem", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting publickkey subsystem", 0); return NULL; } - session->pkeyInit_pkey = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY)); + session->pkeyInit_pkey = + LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PUBLICKEY)); if (!session->pkeyInit_pkey) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a new publickey structure", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a new publickey structure", 0); goto err_exit; } memset(session->pkeyInit_pkey, 0, sizeof(LIBSSH2_PUBLICKEY)); @@ -365,103 +436,135 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session) session->pkeyInit_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_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); - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey version packet advertising version %d support", - (int)LIBSSH2_PUBLICKEY_VERSION); - session->pkeyInit_state = libssh2_NB_state_sent2; } - + if (session->pkeyInit_state == libssh2_NB_state_sent2) { - rc = libssh2_channel_write_ex(session->pkeyInit_channel, 0, (char*)buffer, (s - buffer)); + rc = libssh2_channel_write_ex(session->pkeyInit_channel, 0, + (char *) buffer, (s - buffer)); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending publickkey version packet", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending publickkey version packet", 0); return NULL; - } - else if ((s - buffer) != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey version packet", 0); + } else if ((s - buffer) != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey version packet", 0); goto err_exit; } - + session->pkeyInit_state = libssh2_NB_state_sent3; } - + if (session->pkeyInit_state == libssh2_NB_state_sent3) { while (1) { - rc = libssh2_publickey_packet_receive(session->pkeyInit_pkey, &session->pkeyInit_data, &session->pkeyInit_data_len); + rc = libssh2_publickey_packet_receive(session->pkeyInit_pkey, + &session->pkeyInit_data, + &session->pkeyInit_data_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from publickey subsystem", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response from publickey subsystem", + 0); return NULL; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from publickey subsystem", + 0); goto err_exit; } s = session->pkeyInit_data; - if ((response = libssh2_publickey_response_id(&s, session->pkeyInit_data_len)) < 0) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0); + if ((response = + libssh2_publickey_response_id(&s, + session->pkeyInit_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; + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error */ + { + unsigned long status, descr_len, lang_len; + unsigned char *descr, *lang; - if (s > session->pkeyInit_data + session->pkeyInit_data_len) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0); - goto err_exit; - } + 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; - libssh2_publickey_status_error(NULL, session, status, descr, descr_len); + if (s > + session->pkeyInit_data + session->pkeyInit_data_len) { + libssh2_error(session, + LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Malformed publickey subsystem packet", + 0); goto err_exit; } - - case LIBSSH2_PUBLICKEY_RESPONSE_VERSION: - /* What we want */ - session->pkeyInit_pkey->version = libssh2_ntohu32(s); - if (session->pkeyInit_pkey->version > LIBSSH2_PUBLICKEY_VERSION) { - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Truncating remote publickey version from %lu", - session->pkeyInit_pkey->version); - session->pkeyInit_pkey->version = LIBSSH2_PUBLICKEY_VERSION; - } - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Enabling publickey subsystem version %lu", + + libssh2_publickey_status_error(NULL, session, status, + descr, descr_len); + goto err_exit; + } + + case LIBSSH2_PUBLICKEY_RESPONSE_VERSION: + /* What we want */ + session->pkeyInit_pkey->version = libssh2_ntohu32(s); + if (session->pkeyInit_pkey->version > + LIBSSH2_PUBLICKEY_VERSION) { + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, + "Truncating remote publickey version from %lu", session->pkeyInit_pkey->version); - LIBSSH2_FREE(session, session->pkeyInit_data); - session->pkeyInit_data = NULL; - session->pkeyInit_state = libssh2_NB_state_idle; - return session->pkeyInit_pkey; - - default: - /* Unknown/Unexpected */ - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, - "Unexpected publickey subsystem response, ignoring", 0); - LIBSSH2_FREE(session, session->pkeyInit_data); - session->pkeyInit_data = NULL; + session->pkeyInit_pkey->version = + LIBSSH2_PUBLICKEY_VERSION; + } + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, + "Enabling publickey subsystem version %lu", + session->pkeyInit_pkey->version); + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; + session->pkeyInit_state = libssh2_NB_state_idle; + return session->pkeyInit_pkey; + + default: + /* Unknown/Unexpected */ + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response, ignoring", + 0); + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; } } } /* Never reached except by direct goto */ - err_exit: + err_exit: session->pkeyInit_state = libssh2_NB_state_sent4; if (session->pkeyInit_channel) { rc = libssh2_channel_close(session->pkeyInit_channel); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block closing channel", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block closing channel", 0); return NULL; } } @@ -476,14 +579,17 @@ LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session) session->pkeyInit_state = libssh2_NB_state_idle; return NULL; } + /* }}} */ /* {{{ libssh2_publickey_add_ex * 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, +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[]) { LIBSSH2_CHANNEL *channel = pkey->channel; @@ -496,22 +602,24 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, uns if (pkey->add_state == libssh2_NB_state_idle) { pkey->add_packet = NULL; - - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s publickey", name); + + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Adding %s publickey", + 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; + 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) */ + 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) */ @@ -520,62 +628,84 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, uns pkey->add_packet = LIBSSH2_ALLOC(session, packet_len); if (!pkey->add_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey \"add\" packet", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for publickey \"add\" packet", + 0); return -1; } pkey->add_s = pkey->add_packet; - libssh2_htonu32(pkey->add_s, packet_len - 4); pkey->add_s += 4; - libssh2_htonu32(pkey->add_s, sizeof("add") - 1); pkey->add_s += 4; - memcpy(pkey->add_s, "add", sizeof("add") - 1); pkey->add_s += sizeof("add") - 1; + libssh2_htonu32(pkey->add_s, packet_len - 4); + pkey->add_s += 4; + libssh2_htonu32(pkey->add_s, sizeof("add") - 1); + pkey->add_s += 4; + memcpy(pkey->add_s, "add", sizeof("add") - 1); + pkey->add_s += sizeof("add") - 1; if (pkey->version == 1) { - libssh2_htonu32(pkey->add_s, comment_len); pkey->add_s += 4; + libssh2_htonu32(pkey->add_s, comment_len); + pkey->add_s += 4; if (comment) { - memcpy(pkey->add_s, comment, comment_len); pkey->add_s += comment_len; + memcpy(pkey->add_s, comment, comment_len); + pkey->add_s += comment_len; } - libssh2_htonu32(pkey->add_s, name_len); pkey->add_s += 4; - memcpy(pkey->add_s, name, name_len); pkey->add_s += name_len; - libssh2_htonu32(pkey->add_s, blob_len); pkey->add_s += 4; - memcpy(pkey->add_s, blob, blob_len); pkey->add_s += blob_len; + libssh2_htonu32(pkey->add_s, name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, name, name_len); + pkey->add_s += name_len; + libssh2_htonu32(pkey->add_s, blob_len); + pkey->add_s += 4; + memcpy(pkey->add_s, blob, blob_len); + pkey->add_s += blob_len; } else { /* Version == 2 */ - libssh2_htonu32(pkey->add_s, name_len); pkey->add_s += 4; - memcpy(pkey->add_s, name, name_len); pkey->add_s += name_len; - libssh2_htonu32(pkey->add_s, blob_len); pkey->add_s += 4; - memcpy(pkey->add_s, blob, blob_len); pkey->add_s += blob_len; + libssh2_htonu32(pkey->add_s, name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, name, name_len); + pkey->add_s += name_len; + libssh2_htonu32(pkey->add_s, blob_len); + pkey->add_s += 4; + memcpy(pkey->add_s, blob, blob_len); + pkey->add_s += blob_len; *(pkey->add_s++) = overwrite ? 0x01 : 0; - libssh2_htonu32(pkey->add_s, num_attrs); pkey->add_s += 4; + libssh2_htonu32(pkey->add_s, num_attrs); + pkey->add_s += 4; for(i = 0; i < num_attrs; i++) { - libssh2_htonu32(pkey->add_s, attrs[i].name_len); pkey->add_s += 4; - memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len); pkey->add_s += attrs[i].name_len; - libssh2_htonu32(pkey->add_s, attrs[i].value_len); pkey->add_s += 4; - memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len); pkey->add_s += attrs[i].value_len; + libssh2_htonu32(pkey->add_s, attrs[i].name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len); + pkey->add_s += attrs[i].name_len; + libssh2_htonu32(pkey->add_s, attrs[i].value_len); + pkey->add_s += 4; + memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len); + pkey->add_s += attrs[i].value_len; *(pkey->add_s++) = attrs[i].mandatory ? 0x01 : 0; } } - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld", + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, + "Sending publickey \"add\" packet: type=%s blob_len=%ld num_attrs=%ld", name, blob_len, num_attrs); - + pkey->add_state = libssh2_NB_state_created; } - + if (pkey->add_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)pkey->add_packet, (pkey->add_s - pkey->add_packet)); + rc = libssh2_channel_write_ex(channel, 0, (char *) pkey->add_packet, + (pkey->add_s - pkey->add_packet)); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if ((pkey->add_s - pkey->add_packet) != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey add packet", 0); + } else if ((pkey->add_s - pkey->add_packet) != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey add packet", 0); LIBSSH2_FREE(session, pkey->add_packet); pkey->add_packet = NULL; return -1; } LIBSSH2_FREE(session, pkey->add_packet); pkey->add_packet = NULL; - + pkey->add_state = libssh2_NB_state_sent; } @@ -583,18 +713,20 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, uns if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; } - + pkey->add_state = libssh2_NB_state_idle; - + return rc; } + /* }}} */ /* {{{ libssh2_publickey_remove_ex * Remove an existing publickey so that authentication can no longer be performed using it */ -LIBSSH2_API int -libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, unsigned long name_len, +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; @@ -605,34 +737,46 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, if (pkey->remove_state == libssh2_NB_state_idle) { pkey->remove_packet = NULL; - + pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len); if (!pkey->remove_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for publickey \"remove\" packet", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for publickey \"remove\" packet", + 0); return -1; } pkey->remove_s = pkey->remove_packet; - libssh2_htonu32(pkey->remove_s, packet_len - 4); pkey->remove_s += 4; - libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1); pkey->remove_s += 4; - memcpy(pkey->remove_s, "remove", sizeof("remove") - 1); pkey->remove_s += sizeof("remove") - 1; - libssh2_htonu32(pkey->remove_s, name_len); pkey->remove_s += 4; - memcpy(pkey->remove_s, name, name_len); pkey->remove_s += name_len; - libssh2_htonu32(pkey->remove_s, blob_len); pkey->remove_s += 4; - memcpy(pkey->remove_s, blob, blob_len); pkey->remove_s += blob_len; + libssh2_htonu32(pkey->remove_s, packet_len - 4); + pkey->remove_s += 4; + libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1); + pkey->remove_s += 4; + memcpy(pkey->remove_s, "remove", sizeof("remove") - 1); + pkey->remove_s += sizeof("remove") - 1; + libssh2_htonu32(pkey->remove_s, name_len); + pkey->remove_s += 4; + memcpy(pkey->remove_s, name, name_len); + pkey->remove_s += name_len; + libssh2_htonu32(pkey->remove_s, blob_len); + pkey->remove_s += 4; + memcpy(pkey->remove_s, blob, blob_len); + pkey->remove_s += blob_len; + + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, + "Sending publickey \"remove\" packet: type=%s blob_len=%ld", + name, blob_len); - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"remove\" packet: type=%s blob_len=%ld", name, blob_len); - pkey->remove_state = libssh2_NB_state_created; } - + if (pkey->remove_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)pkey->remove_packet, (pkey->remove_s - pkey->remove_packet)); + rc = libssh2_channel_write_ex(channel, 0, (char *) pkey->remove_packet, + (pkey->remove_s - pkey->remove_packet)); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if ((pkey->remove_s - pkey->remove_packet) != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey remove packet", 0); + } else if ((pkey->remove_s - pkey->remove_packet) != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey remove packet", 0); LIBSSH2_FREE(session, pkey->remove_packet); pkey->remove_packet = NULL; pkey->remove_state = libssh2_NB_state_idle; @@ -640,7 +784,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, } LIBSSH2_FREE(session, pkey->remove_packet); pkey->remove_packet = NULL; - + pkey->remove_state = libssh2_NB_state_sent; } @@ -648,18 +792,20 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; } - + pkey->remove_state = libssh2_NB_state_idle; - + return rc; } + /* }}} */ /* {{{ libssh2_publickey_list_fetch * Fetch a list of supported public key from a server */ LIBSSH2_API int -libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, libssh2_publickey_list **pkey_list) +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; @@ -671,62 +817,81 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l if (pkey->listFetch_state == libssh2_NB_state_idle) { pkey->listFetch_data = NULL; - - pkey->listFetch_s = pkey->listFetch_buffer; - libssh2_htonu32(pkey->listFetch_s, buffer_len - 4); pkey->listFetch_s += 4; - libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1); pkey->listFetch_s += 4; - memcpy(pkey->listFetch_s, "list", sizeof("list") - 1); pkey->listFetch_s += sizeof("list") - 1; - _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, "Sending publickey \"list\" packet"); - + pkey->listFetch_s = pkey->listFetch_buffer; + libssh2_htonu32(pkey->listFetch_s, buffer_len - 4); + pkey->listFetch_s += 4; + libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1); + pkey->listFetch_s += 4; + memcpy(pkey->listFetch_s, "list", sizeof("list") - 1); + pkey->listFetch_s += sizeof("list") - 1; + + _libssh2_debug(session, LIBSSH2_DBG_PUBLICKEY, + "Sending publickey \"list\" packet"); + pkey->listFetch_state = libssh2_NB_state_created; } - + if (pkey->listFetch_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)pkey->listFetch_buffer, (pkey->listFetch_s - pkey->listFetch_buffer)); + rc = libssh2_channel_write_ex(channel, 0, + (char *) pkey->listFetch_buffer, + (pkey->listFetch_s - + pkey->listFetch_buffer)); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send publickey list packet", 0); + } else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey list packet", 0); pkey->listFetch_state = libssh2_NB_state_idle; return -1; } - + pkey->listFetch_state = libssh2_NB_state_sent; } while (1) { - rc = libssh2_publickey_packet_receive(pkey, &pkey->listFetch_data, &pkey->listFetch_data_len); + rc = libssh2_publickey_packet_receive(pkey, &pkey->listFetch_data, + &pkey->listFetch_data_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from publickey subsystem", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from publickey subsystem", + 0); goto err_exit; } pkey->listFetch_s = pkey->listFetch_data; - if ((response = libssh2_publickey_response_id(&pkey->listFetch_s, pkey->listFetch_data_len)) < 0) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Invalid publickey subsystem response code", 0); + if ((response = + libssh2_publickey_response_id(&pkey->listFetch_s, + pkey->listFetch_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: + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: /* Error, or processing complete */ { unsigned long status, descr_len, lang_len; unsigned char *descr, *lang; - - status = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; - descr_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; - descr = pkey->listFetch_s; pkey->listFetch_s += descr_len; - lang_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; - lang = pkey->listFetch_s; pkey->listFetch_s += lang_len; - if (pkey->listFetch_s > pkey->listFetch_data + pkey->listFetch_data_len) { - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Malformed publickey subsystem packet", 0); + status = libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + descr_len = libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + descr = pkey->listFetch_s; + pkey->listFetch_s += descr_len; + lang_len = libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + lang = pkey->listFetch_s; + pkey->listFetch_s += lang_len; + + if (pkey->listFetch_s > + pkey->listFetch_data + pkey->listFetch_data_len) { + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Malformed publickey subsystem packet", 0); goto err_exit; } @@ -739,92 +904,121 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l return 0; } - libssh2_publickey_status_error(pkey, session, status, descr, descr_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); + 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(pkey->listFetch_s); + pkey->listFetch_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 = newlist; - } - if (pkey->version == 1) { - unsigned long comment_len; + list[keys].attrs[0].name = "comment"; + list[keys].attrs[0].name_len = sizeof("comment") - 1; + list[keys].attrs[0].value = (char *) pkey->listFetch_s; + list[keys].attrs[0].value_len = comment_len; + list[keys].attrs[0].mandatory = 0; - comment_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_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 *)pkey->listFetch_s; - list[keys].attrs[0].value_len = comment_len; - list[keys].attrs[0].mandatory = 0; - - pkey->listFetch_s += comment_len; - } else { - list[keys].num_attrs = 0; - list[keys].attrs = NULL; - } - list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; - list[keys].name = pkey->listFetch_s; pkey->listFetch_s += list[keys].name_len; - list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; - list[keys].blob = pkey->listFetch_s; pkey->listFetch_s += list[keys].blob_len; + pkey->listFetch_s += comment_len; } else { - /* Version == 2 */ - list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; - list[keys].name = pkey->listFetch_s; pkey->listFetch_s += list[keys].name_len; - list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_s += 4; - list[keys].blob = pkey->listFetch_s; pkey->listFetch_s += list[keys].blob_len; - list[keys].num_attrs = libssh2_ntohu32(pkey->listFetch_s); pkey->listFetch_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(pkey->listFetch_s); - pkey->listFetch_s += 4; - list[keys].attrs[i].name = (char *)pkey->listFetch_s; - pkey->listFetch_s += list[keys].attrs[i].name_len; - list[keys].attrs[i].value_len = libssh2_ntohu32(pkey->listFetch_s); - pkey->listFetch_s += 4; - list[keys].attrs[i].value = (char *)pkey->listFetch_s; - pkey->listFetch_s += list[keys].attrs[i].value_len; - list[keys].attrs[i].mandatory = 0; /* actually an ignored value */ - } - } else { - list[keys].attrs = NULL; - } + list[keys].num_attrs = 0; + list[keys].attrs = NULL; } - list[keys].packet = pkey->listFetch_data; /* To be FREEd in libssh2_publickey_list_free() */ - keys++; + list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].name = pkey->listFetch_s; + pkey->listFetch_s += list[keys].name_len; + list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].blob = pkey->listFetch_s; + pkey->listFetch_s += list[keys].blob_len; + } else { + /* Version == 2 */ + list[keys].name_len = libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].name = pkey->listFetch_s; + pkey->listFetch_s += list[keys].name_len; + list[keys].blob_len = libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].blob = pkey->listFetch_s; + pkey->listFetch_s += list[keys].blob_len; + list[keys].num_attrs = libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_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(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].attrs[i].name = (char *) pkey->listFetch_s; + pkey->listFetch_s += list[keys].attrs[i].name_len; + list[keys].attrs[i].value_len = + libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].attrs[i].value = (char *) pkey->listFetch_s; + pkey->listFetch_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 = pkey->listFetch_data; /* To be FREEd in libssh2_publickey_list_free() */ + keys++; - list[keys].packet = NULL; /* Terminate the list */ - pkey->listFetch_data = NULL; - break; - default: - /* Unknown/Unexpected */ - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "Unexpected publickey subsystem response, ignoring", 0); - LIBSSH2_FREE(session, pkey->listFetch_data); - pkey->listFetch_data = NULL; + list[keys].packet = NULL; /* Terminate the list */ + pkey->listFetch_data = NULL; + break; + default: + /* Unknown/Unexpected */ + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response, ignoring", + 0); + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; } } /* Only reached via explicit goto */ - err_exit: + err_exit: if (pkey->listFetch_data) { LIBSSH2_FREE(session, pkey->listFetch_data); pkey->listFetch_data = NULL; @@ -835,12 +1029,15 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, unsigned long *num_keys, l pkey->listFetch_state = libssh2_NB_state_idle; return -1; } + /* }}} */ /* {{{ libssh2_publickey_list_free * Free a previously fetched list of public keys */ -LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_publickey_list *pkey_list) +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; @@ -855,12 +1052,14 @@ LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, libssh2_pu LIBSSH2_FREE(session, pkey_list); } + /* }}} */ /* {{{ libssh2_publickey_shutdown * Shutdown the publickey subsystem */ -LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey) +LIBSSH2_API int +libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY * pkey) { LIBSSH2_SESSION *session = pkey->channel->session; @@ -883,12 +1082,13 @@ LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey) LIBSSH2_FREE(session, pkey->listFetch_data); pkey->listFetch_data = NULL; } - + if (libssh2_channel_free(pkey->channel) == PACKET_EAGAIN) { return PACKET_EAGAIN; } - + LIBSSH2_FREE(session, pkey); return 0; } + /* }}} */ diff --git a/src/scp.c b/src/scp.c index cf17ee3..28eef5d 100644 --- a/src/scp.c +++ b/src/scp.c @@ -46,7 +46,8 @@ * otherwise the blocking error code would erase the true * cause of the error. */ -LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb) +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb) { int path_len = strlen(path); int rc; @@ -56,63 +57,78 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch session->scpRecv_size = 0; session->scpRecv_mtime = 0; session->scpRecv_atime = 0; - + session->scpRecv_command_len = path_len + sizeof("scp -f "); - + if (sb) { session->scpRecv_command_len++; } - session->scpRecv_command = LIBSSH2_ALLOC(session, session->scpRecv_command_len); + session->scpRecv_command = + LIBSSH2_ALLOC(session, session->scpRecv_command_len); if (!session->scpRecv_command) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for SCP session", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a command buffer for SCP session", + 0); return NULL; } if (sb) { - memcpy(session->scpRecv_command, "scp -pf ", sizeof("scp -pf ") - 1); - memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path, path_len); + memcpy(session->scpRecv_command, "scp -pf ", + sizeof("scp -pf ") - 1); + memcpy(session->scpRecv_command + sizeof("scp -pf ") - 1, path, + path_len); } else { memcpy(session->scpRecv_command, "scp -f ", sizeof("scp -f ") - 1); - memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path, path_len); + memcpy(session->scpRecv_command + sizeof("scp -f ") - 1, path, + path_len); } session->scpRecv_command[session->scpRecv_command_len - 1] = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP receive"); - + _libssh2_debug(session, LIBSSH2_DBG_SCP, + "Opening channel for SCP receive"); + session->scpRecv_state = libssh2_NB_state_created; } - + if (session->scpRecv_state == libssh2_NB_state_created) { /* Allocate a channel */ do { - session->scpRecv_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1, - LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, - NULL, 0); + session->scpRecv_channel = + libssh2_channel_open_ex(session, "session", + sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, + 0); if (!session->scpRecv_channel) { - if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { + if (libssh2_session_last_errno(session) != + LIBSSH2_ERROR_EAGAIN) { LIBSSH2_FREE(session, session->scpRecv_command); session->scpRecv_command = NULL; session->scpRecv_state = libssh2_NB_state_idle; return NULL; - } - else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0); + } else if (libssh2_session_last_errno(session) == + LIBSSH2_ERROR_EAGAIN) { + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel", 0); return NULL; } } } while (!session->scpRecv_channel); - + session->scpRecv_state = libssh2_NB_state_sent; } if (session->scpRecv_state == libssh2_NB_state_sent) { /* Request SCP for the desired file */ - rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec", sizeof("exec") - 1, (char *)session->scpRecv_command, session->scpRecv_command_len); + rc = libssh2_channel_process_startup(session->scpRecv_channel, "exec", + sizeof("exec") - 1, + (char *) session->scpRecv_command, + session->scpRecv_command_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting SCP startup", 0); return NULL; - } - else if (rc) { + } else if (rc) { LIBSSH2_FREE(session, session->scpRecv_command); session->scpRecv_command = NULL; goto scp_recv_error; @@ -123,40 +139,47 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sending initial wakeup"); /* SCP ACK */ session->scpRecv_response[0] = '\0'; - + session->scpRecv_state = libssh2_NB_state_sent1; } - + if (session->scpRecv_state == libssh2_NB_state_sent1) { - rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1); + rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, + (char *) session->scpRecv_response, 1); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending initial wakeup", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending initial wakeup", 0); return NULL; - } - else if (rc != 1) { + } else if (rc != 1) { goto scp_recv_error; } - + /* Parse SCP response */ session->scpRecv_response_len = 0; - + session->scpRecv_state = libssh2_NB_state_sent2; } - - if ((session->scpRecv_state == libssh2_NB_state_sent2) || (session->scpRecv_state == libssh2_NB_state_sent3)) { - while (sb && (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN)) { + + if ((session->scpRecv_state == libssh2_NB_state_sent2) + || (session->scpRecv_state == libssh2_NB_state_sent3)) { + while (sb + && (session->scpRecv_response_len < + LIBSSH2_SCP_RESPONSE_BUFLEN)) { unsigned char *s, *p; if (session->scpRecv_state == libssh2_NB_state_sent2) { rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, - (char *)session->scpRecv_response + session->scpRecv_response_len, 1); + (char *) session-> + scpRecv_response + + session->scpRecv_response_len, 1); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for SCP response", 0); return NULL; - } - else if (rc <= 0) { + } else if (rc <= 0) { /* Timeout, give up */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Timed out waiting for SCP response", 0); goto scp_recv_error; } session->scpRecv_response_len++; @@ -166,17 +189,25 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch * Set this as the default error for here, if * we are successful it will be replaced */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response, missing Time data", 0); - - session->scpRecv_err_len = libssh2_channel_packet_data_len(session->scpRecv_channel, 0); - session->scpRecv_err_msg = LIBSSH2_ALLOC(session, session->scpRecv_err_len+1); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid data in SCP response, missing Time data", + 0); + + session->scpRecv_err_len = + libssh2_channel_packet_data_len(session-> + scpRecv_channel, 0); + session->scpRecv_err_msg = + LIBSSH2_ALLOC(session, session->scpRecv_err_len + 1); if (!session->scpRecv_err_msg) { goto scp_recv_error; } - memset(session->scpRecv_err_msg, 0, session->scpRecv_err_len+1); - + memset(session->scpRecv_err_msg, 0, + session->scpRecv_err_len + 1); + /* Read the remote error message */ - rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, session->scpRecv_err_msg, session->scpRecv_err_len); + rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, + session->scpRecv_err_msg, + session->scpRecv_err_len); if (rc <= 0) { /* * Since we have alread started reading this packet, it is @@ -184,29 +215,49 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch */ LIBSSH2_FREE(session, session->scpRecv_err_msg); session->scpRecv_err_msg = NULL; - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unknown error while getting error string", + 0); goto scp_recv_error; } - - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpRecv_err_msg, 1); + + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + session->scpRecv_err_msg, 1); session->scpRecv_err_msg = NULL; goto scp_recv_error; } if ((session->scpRecv_response_len > 1) && - ((session->scpRecv_response[session->scpRecv_response_len-1] < '0') || - (session->scpRecv_response[session->scpRecv_response_len-1] > '9')) && - (session->scpRecv_response[session->scpRecv_response_len-1] != ' ') && - (session->scpRecv_response[session->scpRecv_response_len-1] != '\r') && - (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); + ((session-> + scpRecv_response[session->scpRecv_response_len - 1] < + '0') + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] > + '9')) + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + ' ') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\r') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid data in SCP response", 0); goto scp_recv_error; } - if ((session->scpRecv_response_len < 9) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) { - if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { + if ((session->scpRecv_response_len < 9) + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + if (session->scpRecv_response_len == + LIBSSH2_SCP_RESPONSE_BUFLEN) { /* You had your chance */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unterminated response from SCP server", + 0); goto scp_recv_error; } /* Way too short to be an SCP response, or not done yet, short circuit */ @@ -214,125 +265,168 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch } /* We're guaranteed not to go under response_len == 0 by the logic above */ - while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') || (session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) session->scpRecv_response_len--; - session->scpRecv_response[session->scpRecv_response_len] = '\0'; + while ((session-> + scpRecv_response[session->scpRecv_response_len - 1] == + '\r') + || (session-> + scpRecv_response[session->scpRecv_response_len - + 1] == '\n')) + session->scpRecv_response_len--; + session->scpRecv_response[session->scpRecv_response_len] = + '\0'; if (session->scpRecv_response_len < 8) { /* EOL came too soon */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, too short", + 0); goto scp_recv_error; } s = session->scpRecv_response + 1; - p = (unsigned char *)strchr((char *)s, ' '); + p = (unsigned char *) strchr((char *) 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_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, malformed mtime", + 0); goto scp_recv_error; } *(p++) = '\0'; /* Make sure we don't get fooled by leftover values */ errno = 0; - session->scpRecv_mtime = strtol((char *)s, NULL, 10); + session->scpRecv_mtime = strtol((char *) s, NULL, 10); if (errno) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid mtime", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, invalid mtime", + 0); goto scp_recv_error; } - s = (unsigned char *)strchr((char *)p, ' '); + s = (unsigned char *) strchr((char *) 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_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, malformed mtime.usec", + 0); goto scp_recv_error; } /* Ignore mtime.usec */ s++; - p = (unsigned char *)strchr((char *)s, ' '); + p = (unsigned char *) strchr((char *) 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_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, too short or malformed", + 0); goto scp_recv_error; } *(p++) = '\0'; /* Make sure we don't get fooled by leftover values */ errno = 0; - session->scpRecv_atime = strtol((char *)s, NULL, 10); + session->scpRecv_atime = strtol((char *) s, NULL, 10); if (errno) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, invalid atime", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, invalid atime", + 0); goto scp_recv_error; } /* SCP ACK */ session->scpRecv_response[0] = '\0'; - + session->scpRecv_state = libssh2_NB_state_sent3; } - + if (session->scpRecv_state == libssh2_NB_state_sent3) { - rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1); + rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, + (char *) session-> + scpRecv_response, 1); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting to send SCP ACK", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting to send SCP ACK", 0); return NULL; - } - else if (rc != 1) { + } else if (rc != 1) { goto scp_recv_error; } - _libssh2_debug(session, LIBSSH2_DBG_SCP, "mtime = %ld, atime = %ld", session->scpRecv_mtime, session->scpRecv_atime); + _libssh2_debug(session, LIBSSH2_DBG_SCP, + "mtime = %ld, atime = %ld", + session->scpRecv_mtime, session->scpRecv_atime); /* We *should* check that atime.usec is valid, but why let that stop use? */ break; } } - + session->scpRecv_state = libssh2_NB_state_sent4; } if (session->scpRecv_state == libssh2_NB_state_sent4) { session->scpRecv_response_len = 0; - + session->scpRecv_state = libssh2_NB_state_sent5; } - - if ((session->scpRecv_state == libssh2_NB_state_sent5) || (session->scpRecv_state == libssh2_NB_state_sent6)) { + + if ((session->scpRecv_state == libssh2_NB_state_sent5) + || (session->scpRecv_state == libssh2_NB_state_sent6)) { while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { char *s, *p, *e = NULL; if (session->scpRecv_state == libssh2_NB_state_sent5) { rc = libssh2_channel_read_ex(session->scpRecv_channel, 0, - (char *)session->scpRecv_response + session->scpRecv_response_len, 1); + (char *) session-> + scpRecv_response + + session->scpRecv_response_len, 1); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for SCP response", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for SCP response", 0); return NULL; - } - else if (rc <= 0) { + } else if (rc <= 0) { /* Timeout, give up */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Timed out waiting for SCP response", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Timed out waiting for SCP response", 0); goto scp_recv_error; } session->scpRecv_response_len++; if (session->scpRecv_response[0] != 'C') { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server", 0); goto scp_recv_error; } if ((session->scpRecv_response_len > 1) && - (session->scpRecv_response[session->scpRecv_response_len-1] != '\r') && - (session->scpRecv_response[session->scpRecv_response_len-1] != '\n') && - ((session->scpRecv_response[session->scpRecv_response_len-1] < 32) || - (session->scpRecv_response[session->scpRecv_response_len-1] > 126))) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid data in SCP response", 0); + (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\r') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n') + && + ((session-> + scpRecv_response[session->scpRecv_response_len - 1] < 32) + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] > + 126))) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid data in SCP response", 0); goto scp_recv_error; } - if ((session->scpRecv_response_len < 7) || (session->scpRecv_response[session->scpRecv_response_len-1] != '\n')) { - if (session->scpRecv_response_len == LIBSSH2_SCP_RESPONSE_BUFLEN) { + if ((session->scpRecv_response_len < 7) + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + if (session->scpRecv_response_len == + LIBSSH2_SCP_RESPONSE_BUFLEN) { /* You had your chance */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unterminated response from SCP server", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unterminated response from SCP server", + 0); goto scp_recv_error; } /* Way too short to be an SCP response, or not done yet, short circuit */ @@ -340,24 +434,33 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch } /* We're guaranteed not to go under response_len == 0 by the logic above */ - while ((session->scpRecv_response[session->scpRecv_response_len-1] == '\r') || - (session->scpRecv_response[session->scpRecv_response_len-1] == '\n')) { + while ((session-> + scpRecv_response[session->scpRecv_response_len - 1] == + '\r') + || (session-> + scpRecv_response[session->scpRecv_response_len - + 1] == '\n')) { session->scpRecv_response_len--; } - session->scpRecv_response[session->scpRecv_response_len] = '\0'; + session->scpRecv_response[session->scpRecv_response_len] = + '\0'; if (session->scpRecv_response_len < 6) { /* EOL came too soon */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid response from SCP server, too short", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, too short", + 0); goto scp_recv_error; } - s = (char *)session->scpRecv_response + 1; + s = (char *) session->scpRecv_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_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, malformed mode", + 0); goto scp_recv_error; } @@ -366,14 +469,17 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch errno = 0; session->scpRecv_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_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, invalid mode", + 0); goto scp_recv_error; } 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", + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, too short or malformed", 0); goto scp_recv_error; } @@ -383,32 +489,38 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch errno = 0; session->scpRecv_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_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, invalid size", + 0); goto scp_recv_error; } /* SCP ACK */ session->scpRecv_response[0] = '\0'; - + session->scpRecv_state = libssh2_NB_state_sent6; } - + if (session->scpRecv_state == libssh2_NB_state_sent6) { - rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, (char *)session->scpRecv_response, 1); + rc = libssh2_channel_write_ex(session->scpRecv_channel, 0, + (char *) session-> + scpRecv_response, 1); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending SCP ACK", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending SCP ACK", 0); return NULL; - } - else if (rc != 1) { + } else if (rc != 1) { goto scp_recv_error; } - _libssh2_debug(session, LIBSSH2_DBG_SCP, "mode = 0%lo size = %ld", session->scpRecv_mode, session->scpRecv_size); + _libssh2_debug(session, LIBSSH2_DBG_SCP, + "mode = 0%lo size = %ld", session->scpRecv_mode, + session->scpRecv_size); /* We *should* check that basename is valid, but why let that stop us? */ break; } } - + session->scpRecv_state = libssh2_NB_state_sent7; } @@ -423,13 +535,14 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, const ch session->scpRecv_state = libssh2_NB_state_idle; return session->scpRecv_channel; - -scp_recv_error: + + scp_recv_error: while (libssh2_channel_free(session->scpRecv_channel) == PACKET_EAGAIN); session->scpRecv_channel = NULL; session->scpRecv_state = libssh2_NB_state_idle; return NULL; } + /* }}} */ /* {{{ libssh2_scp_send_ex @@ -440,7 +553,8 @@ scp_recv_error: * cause of the error. */ LIBSSH2_API LIBSSH2_CHANNEL * -libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t size, long mtime, long atime) +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 const char *base; @@ -448,124 +562,147 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t if (session->scpSend_state == libssh2_NB_state_idle) { session->scpSend_command_len = path_len + sizeof("scp -t "); - + if (mtime || atime) { session->scpSend_command_len++; } - session->scpSend_command = LIBSSH2_ALLOC(session, session->scpSend_command_len); + session->scpSend_command = + LIBSSH2_ALLOC(session, session->scpSend_command_len); if (!session->scpSend_command) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a command buffer for scp session", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a command buffer for scp session", + 0); return NULL; } if (mtime || atime) { - memcpy(session->scpSend_command, "scp -pt ", sizeof("scp -pt ") - 1); - memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path, path_len); + memcpy(session->scpSend_command, "scp -pt ", + sizeof("scp -pt ") - 1); + memcpy(session->scpSend_command + sizeof("scp -pt ") - 1, path, + path_len); } else { memcpy(session->scpSend_command, "scp -t ", sizeof("scp -t ") - 1); - memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path, path_len); + memcpy(session->scpSend_command + sizeof("scp -t ") - 1, path, + path_len); } session->scpSend_command[session->scpSend_command_len - 1] = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_SCP, "Opening channel for SCP send"); + _libssh2_debug(session, LIBSSH2_DBG_SCP, + "Opening channel for SCP send"); /* Allocate a channel */ - + session->scpSend_state = libssh2_NB_state_created; } - + if (session->scpSend_state == libssh2_NB_state_created) { - session->scpSend_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1, - LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); + session->scpSend_channel = + libssh2_channel_open_ex(session, "session", sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); if (!session->scpSend_channel) { - if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { + if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { /* previous call set libssh2_session_last_error(), pass it through */ LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; session->scpSend_state = libssh2_NB_state_idle; return NULL; - } - else if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0); + } else if (libssh2_session_last_errno(session) == + LIBSSH2_ERROR_EAGAIN) { + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel", 0); return NULL; } } - + session->scpSend_state = libssh2_NB_state_sent; } if (session->scpSend_state == libssh2_NB_state_sent) { /* Request SCP for the desired file */ - rc = libssh2_channel_process_startup(session->scpSend_channel, "exec", sizeof("exec") - 1, - (char *)session->scpSend_command, session->scpSend_command_len); + rc = libssh2_channel_process_startup(session->scpSend_channel, "exec", + sizeof("exec") - 1, + (char *) session->scpSend_command, + session->scpSend_command_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting SCP startup", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting SCP startup", 0); return NULL; - } - else if (rc) { + } else if (rc) { /* previous call set libssh2_session_last_error(), pass it through */ LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Unknown error while getting error string", 0); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unknown error while getting error string", 0); goto scp_send_error; } LIBSSH2_FREE(session, session->scpSend_command); session->scpSend_command = NULL; - + session->scpSend_state = libssh2_NB_state_sent1; } if (session->scpSend_state == libssh2_NB_state_sent1) { /* Wait for ACK */ - rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1); + rc = libssh2_channel_read_ex(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from remote", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response from remote", 0); return NULL; - } - else if ((rc <= 0) || (session->scpSend_response[0] != 0)) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); + } else if ((rc <= 0) || (session->scpSend_response[0] != 0)) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid ACK response from remote", 0); goto scp_send_error; } - + if (mtime || atime) { /* Send mtime and atime to be used for file */ - session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, - "T%ld 0 %ld 0\n", mtime, atime); - _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response); + session->scpSend_response_len = + snprintf((char *) session->scpSend_response, + LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", mtime, + atime); + _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", + session->scpSend_response); } - + session->scpSend_state = libssh2_NB_state_sent2; } /* Send mtime and atime to be used for file */ if (mtime || atime) { if (session->scpSend_state == libssh2_NB_state_sent2) { - rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, + rc = libssh2_channel_write_ex(session->scpSend_channel, 0, + (char *) session->scpSend_response, session->scpSend_response_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending time data for SCP file", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending time data for SCP file", 0); return NULL; - } - else if (rc != session->scpSend_response_len) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send time data for SCP file", 0); + } else if (rc != session->scpSend_response_len) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send time data for SCP file", 0); goto scp_send_error; } - + session->scpSend_state = libssh2_NB_state_sent3; } - + if (session->scpSend_state == libssh2_NB_state_sent3) { /* Wait for ACK */ - rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1); + rc = libssh2_channel_read_ex(session->scpSend_channel, 0, + (char *) session->scpSend_response, + 1); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response", 0); return NULL; - } - else if ((rc <= 0) || (session->scpSend_response[0] != 0)) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); + } else if ((rc <= 0) || (session->scpSend_response[0] != 0)) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid ACK response from remote", 0); goto scp_send_error; } - + session->scpSend_state = libssh2_NB_state_sent4; } } else { @@ -576,62 +713,73 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t if (session->scpSend_state == libssh2_NB_state_sent4) { /* Send mode, size, and basename */ - base = (unsigned char *)strrchr(path, '/'); + base = (unsigned char *) strrchr(path, '/'); if (base) { base++; } else { - base = (unsigned char *)path; + base = (unsigned char *) path; } - session->scpSend_response_len = snprintf((char *)session->scpSend_response, LIBSSH2_SCP_RESPONSE_BUFLEN, - "C0%o %lu %s\n", mode, (unsigned long)size, base); - _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", session->scpSend_response); - + session->scpSend_response_len = + snprintf((char *) session->scpSend_response, + LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %lu %s\n", mode, + (unsigned long) size, base); + _libssh2_debug(session, LIBSSH2_DBG_SCP, "Sent %s", + session->scpSend_response); + session->scpSend_state = libssh2_NB_state_sent5; } - + if (session->scpSend_state == libssh2_NB_state_sent5) { - rc = libssh2_channel_write_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, + rc = libssh2_channel_write_ex(session->scpSend_channel, 0, + (char *) session->scpSend_response, session->scpSend_response_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block send core file data for SCP file", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block send core file data for SCP file", 0); return NULL; - } - else if (rc != session->scpSend_response_len) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send core file data for SCP file", 0); + } else if (rc != session->scpSend_response_len) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send core file data for SCP file", 0); goto scp_send_error; } - + session->scpSend_state = libssh2_NB_state_sent6; } - + if (session->scpSend_state == libssh2_NB_state_sent6) { /* Wait for ACK */ - rc = libssh2_channel_read_ex(session->scpSend_channel, 0, (char *)session->scpSend_response, 1); + rc = libssh2_channel_read_ex(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response", 0); return NULL; - } - else if (rc <= 0) { - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); + } else if (rc <= 0) { + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid ACK response from remote", 0); goto scp_send_error; - } - else if (session->scpSend_response[0] != 0) { + } else if (session->scpSend_response[0] != 0) { /* * Set this as the default error for here, if * we are successful it will be replaced */ - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, "Invalid ACK response from remote", 0); - - session->scpSend_err_len = libssh2_channel_packet_data_len(session->scpSend_channel, 0); - session->scpSend_err_msg = LIBSSH2_ALLOC(session, session->scpSend_err_len+1); + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid ACK response from remote", 0); + + session->scpSend_err_len = + libssh2_channel_packet_data_len(session->scpSend_channel, 0); + session->scpSend_err_msg = + LIBSSH2_ALLOC(session, session->scpSend_err_len + 1); if (!session->scpSend_err_msg) { goto scp_send_error; } - memset(session->scpSend_err_msg, 0, session->scpSend_err_len+1); + memset(session->scpSend_err_msg, 0, session->scpSend_err_len + 1); /* Read the remote error message */ - rc = libssh2_channel_read_ex(session->scpSend_channel, 0, session->scpSend_err_msg, session->scpSend_err_len); + rc = libssh2_channel_read_ex(session->scpSend_channel, 0, + session->scpSend_err_msg, + session->scpSend_err_len); if (rc <= 0) { /* * Since we have alread started reading this packet, it is @@ -641,22 +789,23 @@ libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, size_t session->scpSend_err_msg = NULL; goto scp_send_error; } - - libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, session->scpSend_err_msg, 1); + + libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + session->scpSend_err_msg, 1); session->scpSend_err_msg = NULL; goto scp_send_error; } } - + session->scpSend_state = libssh2_NB_state_idle; return session->scpSend_channel; -scp_send_error: + scp_send_error: while (libssh2_channel_free(session->scpSend_channel) == PACKET_EAGAIN); session->scpSend_channel = NULL; session->scpSend_state = libssh2_NB_state_idle; return NULL; } -/* }}} */ +/* }}} */ diff --git a/src/session.c b/src/session.c index 7b7da28..9c9bd8f 100644 --- a/src/session.c +++ b/src/session.c @@ -52,29 +52,35 @@ /* {{{ libssh2_default_alloc */ -static LIBSSH2_ALLOC_FUNC(libssh2_default_alloc) +static +LIBSSH2_ALLOC_FUNC(libssh2_default_alloc) { - (void)abstract; + (void) abstract; return malloc(count); } + /* }}} */ /* {{{ libssh2_default_free */ -static LIBSSH2_FREE_FUNC(libssh2_default_free) +static +LIBSSH2_FREE_FUNC(libssh2_default_free) { - (void)abstract; + (void) abstract; free(ptr); } + /* }}} */ /* {{{ libssh2_default_realloc */ -static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc) +static +LIBSSH2_REALLOC_FUNC(libssh2_default_realloc) { - (void)abstract; + (void) abstract; return realloc(ptr, count); } + /* }}} */ /* {{{ libssh2_banner_receive @@ -82,7 +88,8 @@ static LIBSSH2_REALLOC_FUNC(libssh2_default_realloc) * Allocate a buffer and store the banner in session->remote.banner * Returns: 0 on success, PACKET_EAGAIN if read would block, 1 on failure */ -static int libssh2_banner_receive(LIBSSH2_SESSION *session) +static int +libssh2_banner_receive(LIBSSH2_SESSION * session) { int ret; int banner_len; @@ -95,31 +102,34 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session) banner_len = session->banner_TxRx_total_send; } - while ((banner_len < (int)sizeof(session->banner_TxRx_banner)) && - ((banner_len == 0) || (session->banner_TxRx_banner[banner_len-1] != '\n'))) { + while ((banner_len < (int) sizeof(session->banner_TxRx_banner)) && + ((banner_len == 0) + || (session->banner_TxRx_banner[banner_len - 1] != '\n'))) { char c = '\0'; - 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) { #ifdef WIN32 switch (WSAGetLastError()) { - case WSAEWOULDBLOCK: - errno = EAGAIN; - break; + case WSAEWOULDBLOCK: + errno = EAGAIN; + break; - case WSAENOTSOCK: - errno = EBADF; - break; + case WSAENOTSOCK: + errno = EBADF; + break; - case WSAENOTCONN: - case WSAECONNABORTED: - errno = WSAENOTCONN; - break; + case WSAENOTCONN: + case WSAECONNABORTED: + errno = WSAENOTCONN; + break; - case WSAEINTR: - errno = EINTR; - break; + case WSAEINTR: + errno = EINTR; + break; } #endif /* WIN32 */ if (errno == EAGAIN) { @@ -133,7 +143,8 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session) } } - if (ret <= 0) continue; + if (ret <= 0) + continue; if (c == '\0') { /* NULLs are not allowed in SSH banners */ @@ -146,8 +157,8 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session) } while (banner_len && - ((session->banner_TxRx_banner[banner_len-1] == '\n') || - (session->banner_TxRx_banner[banner_len-1] == '\r'))) { + ((session->banner_TxRx_banner[banner_len - 1] == '\n') || + (session->banner_TxRx_banner[banner_len - 1] == '\r'))) { banner_len--; } @@ -155,18 +166,22 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session) session->banner_TxRx_state = libssh2_NB_state_idle; session->banner_TxRx_total_send = 0; - 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); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Error allocating space for remote banner", 0); return 1; } memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len); session->remote.banner[banner_len] = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s", session->remote.banner); + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Received Banner: %s", + session->remote.banner); return 0; } + /* }}} */ /* {{{ libssh2_banner_send @@ -177,9 +192,10 @@ static int libssh2_banner_receive(LIBSSH2_SESSION *session) * sent, and this function should then be called with the same argument set * (same data pointer and same data_len) until zero or failure is returned. */ -static int libssh2_banner_send(LIBSSH2_SESSION *session) +static int +libssh2_banner_send(LIBSSH2_SESSION * session) { - char *banner = (char *)LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF; + char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF; int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1; ssize_t ret; #ifdef LIBSSH2DEBUG @@ -189,10 +205,9 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session) if (session->banner_TxRx_state == libssh2_NB_state_idle) { 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; + banner_len = strlen((char *) session->local.banner); + banner = (char *) session->local.banner; } - #ifdef LIBSSH2DEBUG /* Hack and slash to avoid sending CRLF in debug output */ if (banner_len < 256) { @@ -203,17 +218,20 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session) 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 session->banner_TxRx_state = libssh2_NB_state_created; } - ret = send(session->socket_fd, banner+session->banner_TxRx_total_send, banner_len-session->banner_TxRx_total_send, - LIBSSH2_SOCKET_SEND_FLAGS(session)); + ret = + send(session->socket_fd, banner + session->banner_TxRx_total_send, + banner_len - session->banner_TxRx_total_send, + LIBSSH2_SOCKET_SEND_FLAGS(session)); - if (ret != (banner_len-session->banner_TxRx_total_send)) { - if ((ret > 0 ) || ((ret == -1) && (errno == EAGAIN))) { + if (ret != (banner_len - session->banner_TxRx_total_send)) { + if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) { /* the whole packet could not be sent, save the what was */ session->banner_TxRx_total_send += ret; return PACKET_EAGAIN; @@ -229,6 +247,7 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session) return 0; } + /* }}} */ /* @@ -236,8 +255,9 @@ static int libssh2_banner_send(LIBSSH2_SESSION *session) * non-blocking mode based on the 'nonblock' boolean argument. This function * is copied from the libcurl sources with permission. */ -static int _libssh2_nonblock(int sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */) +static int +_libssh2_nonblock(int sockfd, /* operate on this */ + int nonblock /* TRUE or FALSE */ ) { #undef SETBLOCK #define SETBLOCK 0 @@ -276,7 +296,7 @@ static int _libssh2_nonblock(int sockfd, /* operate on this */ #if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0) /* presumably for Amiga */ - return IoctlSocket(sockfd, FIONBIO, (long)nonblock); + return IoctlSocket(sockfd, FIONBIO, (long) nonblock); #undef SETBLOCK #define SETBLOCK 4 #endif @@ -290,7 +310,7 @@ static int _libssh2_nonblock(int sockfd, /* operate on this */ #endif #ifdef HAVE_DISABLED_NONBLOCKING - return 0; /* returns success */ + return 0; /* returns success */ #undef SETBLOCK #define SETBLOCK 6 #endif @@ -304,8 +324,9 @@ static int _libssh2_nonblock(int sockfd, /* operate on this */ * _libssh2_get_socket_nonblocking() gets the given blocking or non-blocking * state of the socket. */ -static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */ -{ +static int +_libssh2_get_socket_nonblocking(int sockfd) +{ /* operate on this */ #undef GETBLOCK #define GETBLOCK 0 #ifdef HAVE_O_NONBLOCK @@ -326,11 +347,12 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */ unsigned int option_value; socklen_t option_len = sizeof(option_value); - if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&option_value, &option_len)) { + if (getsockopt + (sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) { /* Assume blocking on error */ return 1; } - return (int)option_value; + return (int) option_value; #undef GETBLOCK #define GETBLOCK 2 #endif @@ -342,13 +364,13 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */ /* Assume blocking on error */ return 1; } - return (int)b; + return (int) b; #undef GETBLOCK #define GETBLOCK 5 #endif #ifdef HAVE_DISABLED_NONBLOCKING - return 1; /* returns blocking */ + return 1; /* returns blocking */ #undef GETBLOCK #define GETBLOCK 6 #endif @@ -361,7 +383,8 @@ static int _libssh2_get_socket_nonblocking(int sockfd) /* operate on this */ /* {{{ libssh2_banner_set * Set the local banner */ -LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner) +LIBSSH2_API int +libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner) { int banner_len = banner ? strlen(banner) : 0; @@ -376,19 +399,22 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner) 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); + 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); + _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; } + /* }}} */ /* {{{ proto libssh2_session_init @@ -397,39 +423,40 @@ LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, const char *banner) * It's allowable (but unadvisable) to define some but not all of the malloc callbacks * 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_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((*local_alloc)) = libssh2_default_alloc; - LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free; - LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc; + 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; + local_alloc = my_alloc; } if (my_free) { - local_free = my_free; + local_free = my_free; } if (my_realloc) { - local_realloc = 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 (); + 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; } + /* }}} */ /* {{{ libssh2_session_callback_set @@ -439,42 +466,44 @@ LIBSSH2_API LIBSSH2_SESSION *libssh2_session_init_ex( * FIXME: this function relies on that we can typecast function pointers * to void pointers, which isn't allowed in ISO C! */ -LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, - int cbtype, void *callback) +LIBSSH2_API void * +libssh2_session_callback_set(LIBSSH2_SESSION * session, + int cbtype, void *callback) { void *oldcb; switch (cbtype) { - case LIBSSH2_CALLBACK_IGNORE: - oldcb = session->ssh_msg_ignore; - session->ssh_msg_ignore = callback; - return oldcb; + 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); return NULL; } + /* }}} */ /* {{{ proto libssh2_session_startup @@ -484,7 +513,8 @@ LIBSSH2_API void* libssh2_session_callback_set(LIBSSH2_SESSION *session, * callbacks in session * socket *must* be populated with an opened and connected socket. */ -LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket) +LIBSSH2_API int +libssh2_session_startup(LIBSSH2_SESSION * session, int socket) { int rc; @@ -494,12 +524,14 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int 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); + libssh2_error(session, LIBSSH2_ERROR_SOCKET_NONE, + "Bad socket provided", 0); return LIBSSH2_ERROR_SOCKET_NONE; } session->socket_fd = socket; - session->socket_block = !_libssh2_get_socket_nonblocking(session->socket_fd); + session->socket_block = + !_libssh2_get_socket_nonblocking(session->socket_fd); if (session->socket_block) { /* * Since we can't be sure that we are in blocking or there @@ -517,12 +549,13 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket) if (session->startup_state == libssh2_NB_state_created) { rc = libssh2_banner_send(session); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending banner to remote host", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending banner to remote host", 0); return LIBSSH2_ERROR_EAGAIN; - } - else if (rc) { + } else if (rc) { /* Unable to send banner? */ - libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, "Error sending banner to remote host", 0); + libssh2_error(session, LIBSSH2_ERROR_BANNER_SEND, + "Error sending banner to remote host", 0); return LIBSSH2_ERROR_BANNER_SEND; } @@ -532,12 +565,13 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket) if (session->startup_state == libssh2_NB_state_sent) { rc = libssh2_banner_receive(session); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for banner", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for banner", 0); return LIBSSH2_ERROR_EAGAIN; - } - else if (rc) { + } else if (rc) { /* Unable to receive banner from remote */ - libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, "Timeout waiting for banner", 0); + libssh2_error(session, LIBSSH2_ERROR_BANNER_NONE, + "Timeout waiting for banner", 0); return LIBSSH2_ERROR_BANNER_NONE; } @@ -547,11 +581,12 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket) if (session->startup_state == libssh2_NB_state_sent1) { rc = libssh2_kex_exchange(session, 0, &session->startup_key_state); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block exchanging encryption keys", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block exchanging encryption keys", 0); return LIBSSH2_ERROR_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, "Unable to exchange encryption keys", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, + "Unable to exchange encryption keys", 0); return LIBSSH2_ERROR_KEX_FAILURE; } @@ -559,24 +594,29 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket) } if (session->startup_state == libssh2_NB_state_sent2) { - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Requesting userauth service"); + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "Requesting userauth service"); /* Request the userauth service */ session->startup_service[0] = SSH_MSG_SERVICE_REQUEST; - libssh2_htonu32(session->startup_service + 1, sizeof("ssh-userauth") - 1); - memcpy(session->startup_service + 5, "ssh-userauth", sizeof("ssh-userauth") - 1); + libssh2_htonu32(session->startup_service + 1, + sizeof("ssh-userauth") - 1); + memcpy(session->startup_service + 5, "ssh-userauth", + sizeof("ssh-userauth") - 1); session->startup_state = libssh2_NB_state_sent3; } if (session->startup_state == libssh2_NB_state_sent3) { - rc = libssh2_packet_write(session, session->startup_service, sizeof("ssh-userauth") + 5 - 1); + rc = libssh2_packet_write(session, session->startup_service, + sizeof("ssh-userauth") + 5 - 1); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block asking for ssh-userauth service", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block asking for ssh-userauth service", 0); return LIBSSH2_ERROR_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to ask for ssh-userauth service", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to ask for ssh-userauth service", 0); return LIBSSH2_ERROR_SOCKET_SEND; } @@ -584,21 +624,25 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket) } if (session->startup_state == libssh2_NB_state_sent4) { - rc = libssh2_packet_require_ex(session, SSH_MSG_SERVICE_ACCEPT, &session->startup_data, &session->startup_data_len, - 0, NULL, 0, &session->startup_req_state); + rc = libssh2_packet_require_ex(session, SSH_MSG_SERVICE_ACCEPT, + &session->startup_data, + &session->startup_data_len, 0, NULL, 0, + &session->startup_req_state); if (rc == PACKET_EAGAIN) { return LIBSSH2_ERROR_EAGAIN; - } - else if (rc) { + } else if (rc) { return LIBSSH2_ERROR_SOCKET_DISCONNECT; } - session->startup_service_length = libssh2_ntohu32(session->startup_data + 1); + session->startup_service_length = + libssh2_ntohu32(session->startup_data + 1); - if ((session->startup_service_length != (sizeof("ssh-userauth") - 1)) || - strncmp("ssh-userauth", (char *)session->startup_data + 5, session->startup_service_length)) { + if ((session->startup_service_length != (sizeof("ssh-userauth") - 1)) + || strncmp("ssh-userauth", (char *) session->startup_data + 5, + session->startup_service_length)) { LIBSSH2_FREE(session, session->startup_data); session->startup_data = NULL; - libssh2_error(session, LIBSSH2_ERROR_PROTO, "Invalid response received from server", 0); + libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Invalid response received from server", 0); return LIBSSH2_ERROR_PROTO; } LIBSSH2_FREE(session, session->startup_data); @@ -612,18 +656,21 @@ LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int socket) /* just for safety return some error */ return LIBSSH2_ERROR_INVAL; } + /* }}} */ /* {{{ proto libssh2_session_free * Frees the memory allocated to the session * Also closes and frees any channels attached to this session */ -LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session) +LIBSSH2_API int +libssh2_session_free(LIBSSH2_SESSION * session) { int rc; if (session->free_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", session->remote.banner); + _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Freeing session resource", + session->remote.banner); session->state = libssh2_NB_state_created; } @@ -673,11 +720,13 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session) /* Client to Server */ /* crypt */ if (session->local.crypt && session->local.crypt->dtor) { - session->local.crypt->dtor(session, &session->local.crypt_abstract); + 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); + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); } /* mac */ if (session->local.mac && session->local.mac->dtor) { @@ -687,11 +736,13 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session) /* Server to Client */ /* crypt */ if (session->remote.crypt && session->remote.crypt->dtor) { - session->remote.crypt->dtor(session, &session->remote.crypt_abstract); + 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); + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); } /* mac */ if (session->remote.mac && session->remote.mac->dtor) { @@ -840,18 +891,23 @@ LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session) return 0; } + /* }}} */ /* {{{ libssh2_session_disconnect_ex */ -LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, const char *description, const char *lang) +LIBSSH2_API int +libssh2_session_disconnect_ex(LIBSSH2_SESSION * session, int reason, + const char *description, const char *lang) { unsigned char *s; unsigned long descr_len = 0, lang_len = 0; int rc; if (session->disconnect_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_TRANS, "Disconnecting: reason=%d, desc=%s, lang=%s", reason, description, lang); + _libssh2_debug(session, LIBSSH2_DBG_TRANS, + "Disconnecting: reason=%d, desc=%s, lang=%s", reason, + description, lang); if (description) { descr_len = strlen(description); } @@ -861,23 +917,29 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas /* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */ session->disconnect_data_len = descr_len + lang_len + 13; - s = session->disconnect_data = LIBSSH2_ALLOC(session, session->disconnect_data_len); + s = session->disconnect_data = + LIBSSH2_ALLOC(session, session->disconnect_data_len); if (!session->disconnect_data) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for disconnect packet", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for disconnect packet", + 0); session->disconnect_state = libssh2_NB_state_idle; return -1; } *(s++) = SSH_MSG_DISCONNECT; - libssh2_htonu32(s, reason); s += 4; + libssh2_htonu32(s, reason); + s += 4; - libssh2_htonu32(s, descr_len); s += 4; + libssh2_htonu32(s, descr_len); + s += 4; if (description) { memcpy(s, description, descr_len); s += descr_len; } - libssh2_htonu32(s, lang_len); s += 4; + libssh2_htonu32(s, lang_len); + s += 4; if (lang) { memcpy(s, lang, lang_len); s += lang_len; @@ -886,7 +948,8 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas session->disconnect_state = libssh2_NB_state_created; } - rc = libssh2_packet_write(session, session->disconnect_data, session->disconnect_data_len); + rc = libssh2_packet_write(session, session->disconnect_data, + session->disconnect_data_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; } @@ -897,6 +960,7 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas return 0; } + /* }}} */ /* {{{ libssh2_session_methods @@ -904,74 +968,80 @@ LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reas * NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string regardless of actual negotiation * Strings should NOT be freed */ -LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, int method_type) +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; - switch(method_type) { - case LIBSSH2_METHOD_KEX: - method = session->kex; - 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_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_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_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_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_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_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_COMP_SC: + method = (LIBSSH2_KEX_METHOD *) session->remote.comp; + break; - case LIBSSH2_METHOD_LANG_CS: - return ""; - break; + case LIBSSH2_METHOD_LANG_CS: + return ""; + break; - case LIBSSH2_METHOD_LANG_SC: - 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; + 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); + libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No method negotiated", 0); return NULL; } return method->name; } + /* }}} */ /* {{{ libssh2_session_abstract * Retrieve a pointer to the abstract property */ -LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session) +LIBSSH2_API void ** +libssh2_session_abstract(LIBSSH2_SESSION * session) { return &session->abstract; } + /* }}} */ /* {{{ libssh2_session_last_error @@ -980,7 +1050,8 @@ LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session) * Otherwise it is assumed to be owned by libssh2 */ LIBSSH2_API int -libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf) +libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg, + int *errmsg_len, int want_buf) { /* No error to report */ if (!session->err_code) { @@ -991,7 +1062,7 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_ **errmsg = 0; } } else { - *errmsg = (char *)""; + *errmsg = (char *) ""; } } if (errmsg_len) { @@ -1001,8 +1072,7 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_ } if (errmsg) { - char *serrmsg = session->err_msg ? session->err_msg : - (char *)""; + char *serrmsg = session->err_msg ? session->err_msg : (char *) ""; int ownbuf = session->err_msg ? session->err_should_free : 0; if (want_buf) { @@ -1029,23 +1099,26 @@ libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_ return session->err_code; } + /* }}} */ /* {{{ libssh2_session_last_error * Returns error code */ LIBSSH2_API int -libssh2_session_last_errno(LIBSSH2_SESSION *session) +libssh2_session_last_errno(LIBSSH2_SESSION * session) { return session->err_code; } + /* }}} */ /* {{{ libssh2_session_flag * Set/Get session flags * Passing flag==0 will avoid changing session->flags while still returning its current value */ -LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int value) +LIBSSH2_API int +libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value) { if (value) { session->flags |= flag; @@ -1055,16 +1128,19 @@ LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, int val return session->flags; } + /* }}} */ /* {{{ _libssh2_session_set_blocking * Set a session's blocking mode on or off, return the previous status * when this function is called. */ -int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking) +int +_libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking) { int bl = session->socket_block; - _libssh2_debug(session, LIBSSH2_DBG_CONN, "Setting blocking mode on session %d", blocking); + _libssh2_debug(session, LIBSSH2_DBG_CONN, + "Setting blocking mode on session %d", blocking); if (blocking == session->socket_block) { /* avoid if already correct */ return bl; @@ -1075,32 +1151,38 @@ int _libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking) return bl; } + /* }}} */ /* {{{ libssh2_session_set_blocking * Set a channel's blocking mode on or off, similar to a socket's * fcntl(fd, F_SETFL, O_NONBLOCK); type command */ -LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking) +LIBSSH2_API void +libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking) { - (void)_libssh2_session_set_blocking(session, blocking); + (void) _libssh2_session_set_blocking(session, blocking); } + /* }}} */ /* {{{ libssh2_session_get_blocking * Returns a session's blocking mode on or off */ -LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION *session) +LIBSSH2_API int +libssh2_session_get_blocking(LIBSSH2_SESSION * session) { return session->socket_block; } + /* }}} */ /* {{{ libssh2_poll_channel_read * Returns 0 if no data is waiting on channel, * non-0 if data is available */ -LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended) +LIBSSH2_API int +libssh2_poll_channel_read(LIBSSH2_CHANNEL * channel, int extended) { LIBSSH2_SESSION *session = channel->session; LIBSSH2_PACKET *packet = session->packets.head; @@ -1108,8 +1190,9 @@ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended 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)))) { + ((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; } @@ -1118,32 +1201,38 @@ LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended return 0; } + /* }}} */ /* {{{ libssh2_poll_channel_write * Returns 0 if writing to channel would block, * non-0 if data can be written without blocking */ -static inline int libssh2_poll_channel_write(LIBSSH2_CHANNEL *channel) +static inline int +libssh2_poll_channel_write(LIBSSH2_CHANNEL * channel) { return channel->local.window_size ? 1 : 0; } + /* }}} */ /* {{{ libssh2_poll_listener_queued * Returns 0 if no connections are waiting to be accepted * non-0 if one or more connections are available */ -static inline int libssh2_poll_listener_queued(LIBSSH2_LISTENER *listener) +static inline int +libssh2_poll_listener_queued(LIBSSH2_LISTENER * listener) { return listener->queue ? 1 : 0; } + /* }}} */ /* {{{ libssh2_poll * Poll sockets, channels, and listeners for activity */ -LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeout) +LIBSSH2_API int +libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout) { long timeout_remaining; unsigned int i, active_fds; @@ -1154,45 +1243,49 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou #else struct pollfd sockets[256]; - if(nfds > 256) - /* systems without alloca use a fixed-size array, this can be fixed - if we really want to, at least if the compiler is a C99 capable one */ - return -1; + if (nfds > 256) + /* systems without alloca use a fixed-size array, this can be fixed + if we really want to, at least if the compiler is a C99 capable one */ + return -1; #endif /* 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_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_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; + 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; + 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; + fd_set rfds, wfds; struct timeval tv; FD_ZERO(&rfds); @@ -1200,39 +1293,41 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou 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_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_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; + 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; + default: + if (session) + libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, + "Invalid descriptor passed to libssh2_poll()", + 0); + return -1; } } #else @@ -1251,39 +1346,58 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou active_fds = 0; - for (i = 0; i < nfds; i++) { + 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_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; + 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) { @@ -1295,19 +1409,18 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou /* 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 @@ -1317,35 +1430,41 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou #endif /* HAVE_GETTIMEOFDAY */ if (sysret > 0) { - for (i = 0; i < nfds; i++) { + 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; + 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; } } } @@ -1353,16 +1472,16 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou 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 @@ -1372,33 +1491,36 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou #endif if (sysret > 0) { - for (i = 0; i < nfds; i++) { + 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_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_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; + 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; } } } @@ -1407,5 +1529,5 @@ LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, long timeou return active_fds; } -/* }}} */ +/* }}} */ diff --git a/src/sftp.c b/src/sftp.c index 9d3325e..fd4e5e6 100644 --- a/src/sftp.c +++ b/src/sftp.c @@ -85,19 +85,23 @@ /* {{{ libssh2_sftp_packet_add * Add a packet to the SFTP packet brigade */ -static int libssh2_sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data, unsigned long data_len) +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]); + + _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); + 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; @@ -110,32 +114,34 @@ static int libssh2_sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data, unsi sftp->packets.head = packet; } sftp->packets.tail = packet; - + return 0; } + /* }}} */ /* {{{ libssh2_sftp_packet_read * Frame an SFTP packet off the channel */ -static int libssh2_sftp_packet_read(LIBSSH2_SFTP *sftp, int flush) +static int +libssh2_sftp_packet_read(LIBSSH2_SFTP * sftp, int flush) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; - unsigned char buffer[4]; /* To store the packet length */ + unsigned char buffer[4]; /* To store the packet length */ unsigned char *packet; unsigned long packet_len, packet_received; ssize_t bytes_received; int rc; - + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Waiting for packet"); - + if (flush && sftp->partial_packet) { /* When flushing, remove previous partial */ LIBSSH2_FREE(session, sftp->partial_packet); sftp->partial_packet = NULL; } - + /* If there was a previous partial, start using it */ if (sftp->partial_packet) { packet = sftp->partial_packet; @@ -147,41 +153,44 @@ static int libssh2_sftp_packet_read(LIBSSH2_SFTP *sftp, int flush) /* While flushing in blocking mode, check before reading */ return -1; } - rc = libssh2_channel_read_ex(channel, 0, (char *)buffer, 4); + rc = libssh2_channel_read_ex(channel, 0, (char *) buffer, 4); if (flush && (rc < 0)) { /* When flushing, exit quickly */ return -1; - } - else if (rc == PACKET_EAGAIN) { + } else if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (4 != rc) { + } else if (4 != rc) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for FXP packet", 0); return -1; } - + packet_len = libssh2_ntohu32(buffer); _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Data begin - Packet Length: %lu", packet_len); if (packet_len > LIBSSH2_SFTP_PACKET_MAXLEN) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, "SFTP packet too large", 0); + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, + "SFTP packet too large", 0); return -1; } - + packet = LIBSSH2_ALLOC(session, packet_len); if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate SFTP packet", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate SFTP packet", 0); return -1; } - + packet_received = 0; } - + /* Read as much of the packet as we can */ while (packet_len > packet_received) { - bytes_received = libssh2_channel_read_ex(channel, 0, (char *)packet + packet_received, packet_len - packet_received); - + bytes_received = + libssh2_channel_read_ex(channel, 0, + (char *) packet + packet_received, + packet_len - packet_received); + if (flush && (bytes_received < 0)) { if (packet) { /* When flushing, remove packet if existing */ @@ -189,58 +198,60 @@ static int libssh2_sftp_packet_read(LIBSSH2_SFTP *sftp, int flush) } /* When flushing, exit quickly */ return -1; - } - else if (bytes_received == PACKET_EAGAIN) { + } else if (bytes_received == PACKET_EAGAIN) { /* - * We received EAGAIN, save what we have and + * We received EAGAIN, save what we have and * return to EAGAIN to the caller */ sftp->partial_packet = packet; sftp->partial_len = packet_len; sftp->partial_received = packet_received; packet = NULL; - + return PACKET_EAGAIN; - } - else if (bytes_received < 0) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Receive error waiting for SFTP packet", 0); + } else if (bytes_received < 0) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Receive error waiting for SFTP packet", 0); LIBSSH2_FREE(session, packet); return -1; } packet_received += bytes_received; } - + if (libssh2_sftp_packet_add(sftp, packet, packet_len)) { LIBSSH2_FREE(session, packet); return -1; } - + return packet[0]; } + /* }}} */ /* {{{ libssh2_sftp_packet_ask * A la libssh2_packet_ask() */ -static int libssh2_sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type, unsigned long request_id, - unsigned char **data, unsigned long *data_len, int poll_channel) +static int +libssh2_sftp_packet_ask(LIBSSH2_SFTP * sftp, unsigned char packet_type, + unsigned long request_id, unsigned char **data, + unsigned long *data_len, int poll_channel) { LIBSSH2_SESSION *session = sftp->channel->session; LIBSSH2_PACKET *packet = sftp->packets.head; unsigned char match_buf[5]; int match_len = 5; - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Asking for %d packet", (int)packet_type); + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Asking for %d packet", + (int) packet_type); if (poll_channel) { int ret = libssh2_sftp_packet_read(sftp, 0); if (ret == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (ret < 0) { + } else if (ret < 0) { return -1; } } - + match_buf[0] = packet_type; if (packet_type == SSH_FXP_VERSION) { /* Special consideration when matching VERSION packet */ @@ -248,221 +259,258 @@ static int libssh2_sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type } else { libssh2_htonu32(match_buf + 1, request_id); } - + while (packet) { - if (strncmp((char *)packet->data, (char *)match_buf, match_len) == 0) { + if (strncmp((char *) packet->data, (char *) match_buf, match_len) == 0) { *data = packet->data; *data_len = packet->data_len; - + if (packet->prev) { packet->prev->next = packet->next; } else { sftp->packets.head = packet->next; } - + if (packet->next) { packet->next->prev = packet->prev; } else { sftp->packets.tail = packet->prev; } - + LIBSSH2_FREE(session, packet); - + return 0; } packet = packet->next; } return -1; } + /* }}} */ /* {{{ libssh2_sftp_packet_require * A la libssh2_packet_require */ -static int libssh2_sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type, unsigned long request_id, - unsigned char **data, unsigned long *data_len) +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; int ret; - - _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) { + + _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; } - + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { ret = libssh2_sftp_packet_read(sftp, 0); if (ret == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (ret <= 0) { + } 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); + return libssh2_sftp_packet_ask(sftp, packet_type, request_id, data, + data_len, 0); } } - + /* Only reached if the socket died */ return -1; } + /* }}} */ /* {{{ libssh2_sftp_packet_requirev * Requie one of N possible reponses */ -static int libssh2_sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses, - const unsigned char *valid_responses, unsigned long request_id, - unsigned char **data, unsigned long *data_len) +static int +libssh2_sftp_packet_requirev(LIBSSH2_SFTP * sftp, int num_valid_responses, + const unsigned char *valid_responses, + unsigned long request_id, unsigned char **data, + unsigned long *data_len) { int i; int ret; - + /* * If no timeout is active, start a new one and flush * any pending packets - */ + */ if (sftp->requirev_start == 0) { - _libssh2_debug(sftp->channel->session, LIBSSH2_DBG_SFTP, "_requirev(): Initialize timeout"); + _libssh2_debug(sftp->channel->session, LIBSSH2_DBG_SFTP, + "_requirev(): Initialize timeout"); sftp->requirev_start = time(NULL); - + /* Flush */ while (libssh2_sftp_packet_read(sftp, 1) > 0); } - + while (sftp->channel->session->socket_state == LIBSSH2_SOCKET_CONNECTED) { for(i = 0; i < num_valid_responses; i++) { - if (libssh2_sftp_packet_ask(sftp, valid_responses[i], request_id, data, data_len, 0) == 0) { + if (libssh2_sftp_packet_ask + (sftp, valid_responses[i], request_id, data, data_len, + 0) == 0) { /* - * Set to zero before all returns to say + * Set to zero before all returns to say * the timeout is not active */ sftp->requirev_start = 0; return 0; } } - + ret = libssh2_sftp_packet_read(sftp, 0); if ((ret < 0) && (ret != PACKET_EAGAIN)) { sftp->requirev_start = 0; return -1; - } - else if (ret <= 0) { + } else if (ret <= 0) { /* prevent busy-looping */ - long left = LIBSSH2_READ_TIMEOUT - (time(NULL) - sftp->requirev_start); - + long left = + LIBSSH2_READ_TIMEOUT - (time(NULL) - sftp->requirev_start); + if (left <= 0) { sftp->requirev_start = 0; return PACKET_TIMEOUT; - } - else if (sftp->channel->session->socket_block && (libssh2_waitsocket(sftp->channel->session, left) <= 0 )) { + } else if (sftp->channel->session->socket_block + && (libssh2_waitsocket(sftp->channel->session, left) <= + 0)) { sftp->requirev_start = 0; return PACKET_TIMEOUT; - } - else if (ret == PACKET_EAGAIN) { + } else if (ret == PACKET_EAGAIN) { return PACKET_EAGAIN; } } } - + sftp->requirev_start = 0; return -1; } + /* }}} */ /* {{{ libssh2_sftp_attrsize * Size that attr will occupy when turned into a bin struct */ -static int libssh2_sftp_attrsize(const LIBSSH2_SFTP_ATTRIBUTES *attrs) +static int +libssh2_sftp_attrsize(const LIBSSH2_SFTP_ATTRIBUTES * attrs) { - int attrsize = 4; /* flags(4) */ - + 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 */ - + + 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; } + /* }}} */ /* {{{ libssh2_sftp_attr2bin * Populate attributes into an SFTP block */ -static int libssh2_sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES *attrs) +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 | + 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; - + + libssh2_htonu32(s, attrs->flags & flag_mask); + s += 4; + if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { - libssh2_htonu64(s, attrs->filesize); s += 8; + 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; + 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; + 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; + libssh2_htonu32(s, attrs->atime); + s += 4; + libssh2_htonu32(s, attrs->mtime); + s += 4; } - + return (s - p); } + /* }}} */ /* {{{ libssh2_sftp_bin2attr */ -static int libssh2_sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES *attrs, const unsigned char *p) +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; - + attrs->flags = libssh2_ntohu32(s); + s += 4; + if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { - attrs->filesize = libssh2_ntohu64(s); s += 8; + 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; + 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; + 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; + attrs->atime = libssh2_ntohu32(s); + s += 4; + attrs->mtime = libssh2_ntohu32(s); + s += 4; } - + return (s - p); } + /* }}} */ /* ************ @@ -476,28 +524,29 @@ LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor); */ LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor) { - LIBSSH2_SFTP *sftp = (LIBSSH2_SFTP*)(*channel_abstract); - - (void)session_abstract; - (void)channel; - + LIBSSH2_SFTP *sftp = (LIBSSH2_SFTP *) (*channel_abstract); + + (void) session_abstract; + (void) channel; + /* Loop through handles closing them */ while (sftp->handles) { libssh2_sftp_close_handle(sftp->handles); } - + /* Free the partial packet storage for libssh2_sftp_packet_read */ if (sftp->partial_packet) { LIBSSH2_FREE(session, sftp->partial_packet); } - + /* Free the packet storage for _libssh2_sftp_packet_readdir */ if (sftp->readdir_packet) { LIBSSH2_FREE(session, sftp->readdir_packet); } - + LIBSSH2_FREE(session, sftp); } + /* }}} */ /* {{{ libssh2_sftp_init @@ -507,138 +556,165 @@ LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor) * otherwise the blocking error code would erase the true * cause of the error. */ -LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session) +LIBSSH2_API LIBSSH2_SFTP * +libssh2_sftp_init(LIBSSH2_SESSION * session) { unsigned char *data, *s; unsigned long data_len; int rc; if (session->sftpInit_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Initializing SFTP subsystem"); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, + "Initializing SFTP subsystem"); session->sftpInit_sftp = NULL; session->sftpInit_state = libssh2_NB_state_created; } - + if (session->sftpInit_state == libssh2_NB_state_created) { - session->sftpInit_channel = libssh2_channel_open_ex(session, "session", sizeof("session") - 1, - LIBSSH2_CHANNEL_WINDOW_DEFAULT, LIBSSH2_CHANNEL_PACKET_DEFAULT, - NULL, 0); + session->sftpInit_channel = + libssh2_channel_open_ex(session, "session", sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); if (!session->sftpInit_channel) { if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block starting up channel", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel", 0); return NULL; - } - else if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to startup channel", 0); + } else if (libssh2_session_last_errno(session) != + LIBSSH2_ERROR_EAGAIN) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to startup channel", 0); session->sftpInit_state = libssh2_NB_state_idle; return NULL; } } - + session->sftpInit_state = libssh2_NB_state_sent; } - + if (session->sftpInit_state == libssh2_NB_state_sent) { - rc = libssh2_channel_process_startup(session->sftpInit_channel, "subsystem", sizeof("subsystem") - 1, - "sftp", strlen("sftp")); + rc = libssh2_channel_process_startup(session->sftpInit_channel, + "subsystem", + sizeof("subsystem") - 1, "sftp", + strlen("sftp")); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block to request SFTP subsystem", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block to request SFTP subsystem", 0); return NULL; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Unable to request SFTP subsystem", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to request SFTP subsystem", 0); goto sftp_init_error; } - + session->sftpInit_state = libssh2_NB_state_sent1; } - + if (session->sftpInit_state == libssh2_NB_state_sent1) { - rc = libssh2_channel_handle_extended_data2(session->sftpInit_channel, LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); + rc = libssh2_channel_handle_extended_data2(session->sftpInit_channel, + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting handle extended data", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting handle extended data", 0); return NULL; } - + session->sftpInit_sftp = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP)); if (!session->sftpInit_sftp) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate a new SFTP structure", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a new SFTP structure", 0); goto sftp_init_error; } memset(session->sftpInit_sftp, 0, sizeof(LIBSSH2_SFTP)); session->sftpInit_sftp->channel = session->sftpInit_channel; session->sftpInit_sftp->request_id = 0; - + libssh2_htonu32(session->sftpInit_buffer, 5); session->sftpInit_buffer[4] = SSH_FXP_INIT; libssh2_htonu32(session->sftpInit_buffer + 5, LIBSSH2_SFTP_VERSION); - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Sending FXP_INIT packet advertising version %d support", - (int)LIBSSH2_SFTP_VERSION); - + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, + "Sending FXP_INIT packet advertising version %d support", + (int) LIBSSH2_SFTP_VERSION); + session->sftpInit_state = libssh2_NB_state_sent2; } - + if (session->sftpInit_state == libssh2_NB_state_sent2) { - rc = libssh2_channel_write_ex(session->sftpInit_channel, 0, (char *)session->sftpInit_buffer, 9); + rc = libssh2_channel_write_ex(session->sftpInit_channel, 0, + (char *) session->sftpInit_buffer, 9); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending SSH_FXP_INIT", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending SSH_FXP_INIT", 0); return NULL; - } - else if (9 != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send SSH_FXP_INIT", 0); + } else if (9 != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send SSH_FXP_INIT", 0); goto sftp_init_error; } - + session->sftpInit_state = libssh2_NB_state_sent3; } - + /* For initiallization we are requiring blocking, probably reasonable */ - rc = libssh2_sftp_packet_require(session->sftpInit_sftp, SSH_FXP_VERSION, 0, &data, &data_len); + rc = libssh2_sftp_packet_require(session->sftpInit_sftp, SSH_FXP_VERSION, + 0, &data, &data_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for response from SFTP subsystem", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response from SFTP subsystem", + 0); return NULL; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for response from SFTP subsystem", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from SFTP subsystem", 0); goto sftp_init_error; } if (data_len < 5) { - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Invalid SSH_FXP_VERSION response", 0); + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Invalid SSH_FXP_VERSION response", 0); goto sftp_init_error; } - + s = data + 1; - session->sftpInit_sftp->version = libssh2_ntohu32(s); s += 4; + session->sftpInit_sftp->version = libssh2_ntohu32(s); + s += 4; if (session->sftpInit_sftp->version > LIBSSH2_SFTP_VERSION) { - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Truncating remote SFTP version from %lu", session->sftpInit_sftp->version); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, + "Truncating remote SFTP version from %lu", + session->sftpInit_sftp->version); session->sftpInit_sftp->version = LIBSSH2_SFTP_VERSION; } - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Enabling SFTP version %lu compatability", session->sftpInit_sftp->version); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, + "Enabling SFTP version %lu compatability", + session->sftpInit_sftp->version); while (s < (data + data_len)) { unsigned char *extension_name, *extension_data; unsigned long extname_len, extdata_len; - - extname_len = libssh2_ntohu32(s); s += 4; - extension_name = s; s += extname_len; - - extdata_len = libssh2_ntohu32(s); s += 4; - extension_data = s; s += extdata_len; - + + extname_len = libssh2_ntohu32(s); + s += 4; + extension_name = s; + s += extname_len; + + extdata_len = libssh2_ntohu32(s); + s += 4; + extension_data = s; + s += extdata_len; + /* TODO: Actually process extensions */ } LIBSSH2_FREE(session, data); - + /* Make sure that when the channel gets closed, the SFTP service is shut down too */ session->sftpInit_sftp->channel->abstract = session->sftpInit_sftp; session->sftpInit_sftp->channel->close_cb = libssh2_sftp_dtor; session->sftpInit_state = libssh2_NB_state_idle; return session->sftpInit_sftp; - -sftp_init_error: + + sftp_init_error: while (libssh2_channel_free(session->sftpInit_channel) == PACKET_EAGAIN); session->sftpInit_channel = NULL; if (session->sftpInit_sftp) { @@ -648,12 +724,14 @@ sftp_init_error: session->sftpInit_state = libssh2_NB_state_idle; return NULL; } + /* }}} */ /* {{{ libssh2_sftp_shutdown * Shutsdown the SFTP subsystem */ -LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp) +LIBSSH2_API int +libssh2_sftp_shutdown(LIBSSH2_SFTP * sftp) { /* * Make sure all memory used in the state variables are free @@ -706,9 +784,10 @@ LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp) LIBSSH2_FREE(sftp->channel->session, sftp->symlink_packet); sftp->symlink_packet = NULL; } - + return libssh2_channel_free(sftp->channel); } + /* }}} */ /* ******************************* @@ -718,8 +797,9 @@ LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp) /* {{{ libssh2_sftp_open_ex */ 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_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; @@ -729,48 +809,66 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int file }; unsigned long data_len; unsigned char *data, *s; - static const unsigned char fopen_responses[2] = { SSH_FXP_HANDLE, SSH_FXP_STATUS }; + static const unsigned char fopen_responses[2] = + { SSH_FXP_HANDLE, SSH_FXP_STATUS }; int rc; - + if (sftp->open_state == libssh2_NB_state_idle) { /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) + flags(4) */ - sftp->open_packet_len = filename_len + 13 + - ((open_type == LIBSSH2_SFTP_OPENFILE) ? (4 + libssh2_sftp_attrsize(&attrs)) : 0); - + sftp->open_packet_len = filename_len + 13 + + ((open_type == + LIBSSH2_SFTP_OPENFILE) ? (4 + + libssh2_sftp_attrsize(&attrs)) : 0); + s = sftp->open_packet = LIBSSH2_ALLOC(session, sftp->open_packet_len); if (!sftp->open_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_OPEN or FXP_OPENDIR packet", 0); + 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, sftp->open_packet_len - 4); s += 4; - *(s++) = (open_type == LIBSSH2_SFTP_OPENFILE) ? SSH_FXP_OPEN : SSH_FXP_OPENDIR; + attrs.permissions = mode | + ((open_type == + LIBSSH2_SFTP_OPENFILE) ? LIBSSH2_SFTP_ATTR_PFILETYPE_FILE : + LIBSSH2_SFTP_ATTR_PFILETYPE_DIR); + + libssh2_htonu32(s, sftp->open_packet_len - 4); + s += 4; + *(s++) = + (open_type == + LIBSSH2_SFTP_OPENFILE) ? SSH_FXP_OPEN : SSH_FXP_OPENDIR; sftp->open_request_id = sftp->request_id++; - libssh2_htonu32(s, sftp->open_request_id); s += 4; - libssh2_htonu32(s, filename_len); s += 4; - memcpy(s, filename, filename_len); s += filename_len; + libssh2_htonu32(s, sftp->open_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; + 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"); - + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Sending %s open request", + (open_type == + LIBSSH2_SFTP_OPENFILE) ? "file" : "directory"); + sftp->open_state = libssh2_NB_state_created; } - + if (sftp->open_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)sftp->open_packet, sftp->open_packet_len); + rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->open_packet, + sftp->open_packet_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block sending FXP_OPEN or FXP_OPENDIR command", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending FXP_OPEN or FXP_OPENDIR command", + 0); return NULL; - } - else if (sftp->open_packet_len != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_OPEN or FXP_OPENDIR command", 0); + } else if (sftp->open_packet_len != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_OPEN or FXP_OPENDIR command", 0); LIBSSH2_FREE(session, sftp->open_packet); sftp->open_packet = NULL; sftp->open_state = libssh2_NB_state_idle; @@ -778,41 +876,49 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int file } LIBSSH2_FREE(session, sftp->open_packet); sftp->open_packet = NULL; - + sftp->open_state = libssh2_NB_state_sent; } - + if (sftp->open_state == libssh2_NB_state_sent) { - rc = libssh2_sftp_packet_requirev(sftp, 2, fopen_responses, sftp->open_request_id, &data, &data_len); + rc = libssh2_sftp_packet_requirev(sftp, 2, fopen_responses, + sftp->open_request_id, &data, + &data_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block waiting for status message", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for status message", 0); return NULL; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timeout waiting for status message", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); sftp->open_state = libssh2_NB_state_idle; return NULL; } } - + sftp->open_state = libssh2_NB_state_idle; - + if (data[0] == SSH_FXP_STATUS) { - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Failed opening remote file", 0); + 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_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_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 */ @@ -820,51 +926,59 @@ libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int file } 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_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; } + /* }}} */ /* {{{ libssh2_sftp_read * Read from an SFTP file handle */ -LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen) +LIBSSH2_API ssize_t +libssh2_sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer, + size_t buffer_maxlen) { - LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; unsigned long data_len, request_id; /* 25 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) + offset(8) + length(4) */ ssize_t packet_len = handle->handle_len + 25; unsigned char *packet, *s, *data; - static const unsigned char read_responses[2] = { SSH_FXP_DATA, SSH_FXP_STATUS }; + static const unsigned char read_responses[2] = + { SSH_FXP_DATA, SSH_FXP_STATUS }; size_t bytes_read = 0; size_t bytes_requested = 0; size_t total_read = 0; int retcode; - + if (sftp->read_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Reading %lu bytes from SFTP handle", (unsigned long)buffer_maxlen); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, + "Reading %lu bytes from SFTP handle", + (unsigned long) buffer_maxlen); packet = LIBSSH2_ALLOC(session, packet_len); if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_CLOSE packet", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_CLOSE packet", 0); return -1; } sftp->read_state = libssh2_NB_state_allocated; @@ -873,7 +987,7 @@ LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, request_id = sftp->read_request_id; total_read = sftp->read_total_read; } - + while (total_read < buffer_maxlen) { s = packet; /* @@ -886,11 +1000,12 @@ LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, if (bytes_requested > LIBSSH2_SFTP_PACKET_MAXLEN - 10) { bytes_requested = LIBSSH2_SFTP_PACKET_MAXLEN - 10; } - #ifdef LIBSSH2_DEBUG_SFTP - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Requesting %lu bytes from SFTP handle", (unsigned long)bytes_requested); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, + "Requesting %lu bytes from SFTP handle", + (unsigned long) bytes_requested); #endif - + if (sftp->read_state == libssh2_NB_state_allocated) { libssh2_htonu32(s, packet_len - 4); s += 4; @@ -900,29 +1015,31 @@ LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, s += 4; libssh2_htonu32(s, handle->handle_len); s += 4; - + memcpy(s, handle->handle, handle->handle_len); s += handle->handle_len; - + libssh2_htonu64(s, handle->u.file.offset); s += 8; - + libssh2_htonu32(s, buffer_maxlen); s += 4; - + sftp->read_state = libssh2_NB_state_created; } - + if (sftp->read_state == libssh2_NB_state_created) { - retcode = libssh2_channel_write_ex(channel, 0, (char *)packet, packet_len); + retcode = + libssh2_channel_write_ex(channel, 0, (char *) packet, + packet_len); if (retcode == PACKET_EAGAIN) { sftp->read_packet = packet; sftp->read_request_id = request_id; sftp->read_total_read = total_read; return PACKET_EAGAIN; - } - else if (packet_len != retcode) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_READ command", 0); + } else if (packet_len != retcode) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_READ command", 0); LIBSSH2_FREE(session, packet); sftp->read_packet = NULL; sftp->read_state = libssh2_NB_state_idle; @@ -933,77 +1050,84 @@ LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, char *buffer, sftp->read_total_read = total_read; sftp->read_state = libssh2_NB_state_sent; } - + if (sftp->read_state == libssh2_NB_state_sent) { - retcode = libssh2_sftp_packet_requirev(sftp, 2, read_responses, request_id, &data, &data_len); + 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); + } else if (retcode) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); LIBSSH2_FREE(session, packet); sftp->read_packet = NULL; sftp->read_state = libssh2_NB_state_idle; return -1; } - + sftp->read_state = libssh2_NB_state_sent1; } - + switch (data[0]) { - case SSH_FXP_STATUS: - retcode = libssh2_ntohu32(data + 5); + case SSH_FXP_STATUS: + retcode = libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, packet); + LIBSSH2_FREE(session, data); + sftp->read_packet = NULL; + sftp->read_state = libssh2_NB_state_idle; + + if (retcode == LIBSSH2_FX_EOF) { + return total_read; + } else { + sftp->last_errno = retcode; + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error", 0); + return -1; + } + + case SSH_FXP_DATA: + bytes_read = libssh2_ntohu32(data + 5); + if (bytes_read > (data_len - 9)) { LIBSSH2_FREE(session, packet); - LIBSSH2_FREE(session, data); sftp->read_packet = NULL; sftp->read_state = libssh2_NB_state_idle; - - if (retcode == LIBSSH2_FX_EOF) { - return total_read; - } else { - sftp->last_errno = retcode; - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); - return -1; - } - - case SSH_FXP_DATA: - bytes_read = libssh2_ntohu32(data + 5); - if (bytes_read > (data_len - 9)) { - LIBSSH2_FREE(session, packet); - sftp->read_packet = NULL; - sftp->read_state = libssh2_NB_state_idle; - return -1; - } + return -1; + } #ifdef LIBSSH2_DEBUG_SFTP - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%lu bytes returned", (unsigned long)bytes_read); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%lu bytes returned", + (unsigned long) bytes_read); #endif - memcpy(buffer + total_read, data + 9, bytes_read); - handle->u.file.offset += bytes_read; - total_read += bytes_read; - LIBSSH2_FREE(session, data); - /* - * Set the state back to allocated, so a new one will be - * created to either request more data or get EOF - */ - sftp->read_state = libssh2_NB_state_allocated; + memcpy(buffer + total_read, data + 9, bytes_read); + handle->u.file.offset += bytes_read; + total_read += bytes_read; + LIBSSH2_FREE(session, data); + /* + * Set the state back to allocated, so a new one will be + * created to either request more data or get EOF + */ + sftp->read_state = libssh2_NB_state_allocated; } } - + LIBSSH2_FREE(session, packet); sftp->read_packet = NULL; sftp->read_state = libssh2_NB_state_idle; return total_read; } + /* }}} */ /* {{{ libssh2_sftp_readdir * Read from an SFTP directory handle */ -LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffer, size_t buffer_maxlen, - char *longentry, size_t longentry_maxlen, - LIBSSH2_SFTP_ATTRIBUTES *attrs) +LIBSSH2_API int +libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE * handle, char *buffer, + size_t buffer_maxlen, char *longentry, + size_t longentry_maxlen, + LIBSSH2_SFTP_ATTRIBUTES * attrs) { - LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; LIBSSH2_SFTP_ATTRIBUTES attrs_dummy; @@ -1013,16 +1137,16 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffe unsigned char *s, *data; unsigned char read_responses[2] = { SSH_FXP_NAME, SSH_FXP_STATUS }; int retcode; - + if (sftp->readdir_state == libssh2_NB_state_idle) { if (handle->u.dir.names_left) { /* - * A prior request returned more than one directory entry, - * feed it back from the buffer + * A prior request returned more than one directory entry, + * feed it back from the buffer */ - unsigned char *s = (unsigned char *)handle->u.dir.next_name; + unsigned char *s = (unsigned char *) handle->u.dir.next_name; unsigned long real_filename_len = libssh2_ntohu32(s); - + filename_len = real_filename_len; s += 4; if (filename_len > buffer_maxlen) { @@ -1030,18 +1154,18 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffe } memcpy(buffer, s, filename_len); s += real_filename_len; - + /* The filename is not null terminated, make it so if possible */ if (filename_len < buffer_maxlen) { buffer[filename_len] = '\0'; } - + if ((longentry == NULL) || (longentry_maxlen == 0)) { /* Skip longname */ s += 4 + libssh2_ntohu32(s); } else { unsigned long real_longentry_len = libssh2_ntohu32(s); - + longentry_len = real_longentry_len; s += 4; if (longentry_len > longentry_maxlen) { @@ -1049,36 +1173,39 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffe } memcpy(longentry, s, longentry_len); s += real_longentry_len; - + /* The longentry is not null terminated, make it so if possible */ if (longentry_len < longentry_maxlen) { longentry[longentry_len] = '\0'; } } - + if (attrs) { memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); } s += libssh2_sftp_bin2attr(attrs ? attrs : &attrs_dummy, s); - - handle->u.dir.next_name = (char *)s; + + handle->u.dir.next_name = (char *) s; if ((--handle->u.dir.names_left) == 0) { LIBSSH2_FREE(session, handle->u.dir.names_packet); } - - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "libssh2_sftp_readdir_ex() return %d", filename_len); + + _libssh2_debug(session, LIBSSH2_DBG_SFTP, + "libssh2_sftp_readdir_ex() return %d", + filename_len); return filename_len; } - + /* Request another entry(entries?) */ - + s = sftp->readdir_packet = LIBSSH2_ALLOC(session, packet_len); if (!sftp->readdir_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate memory for FXP_READDIR packet", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_READDIR packet", + 0); return -1; } - + libssh2_htonu32(s, packet_len - 4); s += 4; *(s++) = SSH_FXP_READDIR; @@ -1089,35 +1216,42 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffe s += 4; memcpy(s, handle->handle, handle->handle_len); s += handle->handle_len; - + sftp->readdir_state = libssh2_NB_state_created; } - + if (sftp->readdir_state == libssh2_NB_state_created) { - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Reading entries from directory handle"); - if ((retcode = libssh2_channel_write_ex(channel, 0, (char *)sftp->readdir_packet, packet_len)) == PACKET_EAGAIN) { + _libssh2_debug(session, LIBSSH2_DBG_SFTP, + "Reading entries from directory handle"); + if ((retcode = + libssh2_channel_write_ex(channel, 0, + (char *) sftp->readdir_packet, + packet_len)) == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (packet_len != retcode) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_READ command", 0); + } else if (packet_len != retcode) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_READ command", 0); LIBSSH2_FREE(session, sftp->readdir_packet); sftp->readdir_packet = NULL; sftp->readdir_state = libssh2_NB_state_idle; return -1; } - + LIBSSH2_FREE(session, sftp->readdir_packet); sftp->readdir_packet = NULL; - + sftp->readdir_state = libssh2_NB_state_sent; } - retcode = libssh2_sftp_packet_requirev(sftp, 2, read_responses, sftp->readdir_request_id, &data, &data_len); + retcode = + libssh2_sftp_packet_requirev(sftp, 2, read_responses, + sftp->readdir_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); + } else if (retcode) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); sftp->readdir_state = libssh2_NB_state_idle; return -1; } @@ -1130,14 +1264,16 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffe return 0; } else { sftp->last_errno = retcode; - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error", 0); sftp->readdir_state = libssh2_NB_state_idle; return -1; } } num_names = libssh2_ntohu32(data + 5); - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%lu entries returned", num_names); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%lu entries returned", + num_names); if (num_names <= 0) { LIBSSH2_FREE(session, data); sftp->readdir_state = libssh2_NB_state_idle; @@ -1160,8 +1296,10 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffe 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_sftp_bin2attr(attrs, data + 13 + real_filename_len + + (4 + + libssh2_ntohu32(data + 13 + + real_filename_len))); } LIBSSH2_FREE(session, data); @@ -1171,21 +1309,25 @@ LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, char *buffe handle->u.dir.names_left = num_names; handle->u.dir.names_packet = data; - handle->u.dir.next_name = (char *)data + 9; + handle->u.dir.next_name = (char *) data + 9; sftp->readdir_state = libssh2_NB_state_idle; - + /* Be lazy, just use the name popping mechanism from the start of the function */ - return libssh2_sftp_readdir_ex(handle, buffer, buffer_maxlen, longentry, longentry_maxlen, attrs); + return libssh2_sftp_readdir_ex(handle, buffer, buffer_maxlen, longentry, + longentry_maxlen, attrs); } + /* }}} */ /* {{{ libssh2_sftp_write * Write data to a file handle */ -LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, size_t count) +LIBSSH2_API ssize_t +libssh2_sftp_write(LIBSSH2_SFTP_HANDLE * handle, const char *buffer, + size_t count) { - LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; unsigned long data_len, retcode; @@ -1193,34 +1335,46 @@ LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char * ssize_t packet_len = handle->handle_len + count + 25; unsigned char *s, *data; int rc; - + if (sftp->write_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Writing %lu bytes", (unsigned long)count); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Writing %lu bytes", + (unsigned long) count); s = sftp->write_packet = LIBSSH2_ALLOC(session, packet_len); if (!sftp->write_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_WRITE packet", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_WRITE packet", 0); return -1; } - - libssh2_htonu32(s, packet_len - 4); s += 4; + + libssh2_htonu32(s, packet_len - 4); + s += 4; *(s++) = SSH_FXP_WRITE; sftp->write_request_id = sftp->request_id++; - libssh2_htonu32(s, sftp->write_request_id); s += 4; - libssh2_htonu32(s, handle->handle_len); s += 4; - memcpy(s, handle->handle, handle->handle_len); s += handle->handle_len; - libssh2_htonu64(s, handle->u.file.offset); s += 8; - libssh2_htonu32(s, count); s += 4; - memcpy(s, buffer, count); s += count; - + libssh2_htonu32(s, sftp->write_request_id); + s += 4; + libssh2_htonu32(s, handle->handle_len); + s += 4; + memcpy(s, handle->handle, handle->handle_len); + s += handle->handle_len; + libssh2_htonu64(s, handle->u.file.offset); + s += 8; + libssh2_htonu32(s, count); + s += 4; + memcpy(s, buffer, count); + s += count; + sftp->write_state = libssh2_NB_state_created; } - + if (sftp->write_state == libssh2_NB_state_created) { - if ((rc = libssh2_channel_write_ex(channel, 0, (char *)sftp->write_packet, packet_len)) == PACKET_EAGAIN) { + if ((rc = + libssh2_channel_write_ex(channel, 0, (char *) sftp->write_packet, + packet_len)) == PACKET_EAGAIN) { return PACKET_EAGAIN; } if (packet_len != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_READ command", 0); + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_READ command", 0); LIBSSH2_FREE(session, sftp->write_packet); sftp->write_packet = NULL; sftp->write_state = libssh2_NB_state_idle; @@ -1230,77 +1384,92 @@ LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char * sftp->write_packet = NULL; sftp->write_state = libssh2_NB_state_sent; } - - rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->write_request_id, &data, &data_len); + + rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->write_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); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); sftp->write_state = libssh2_NB_state_idle; return -1; } - + sftp->write_state = libssh2_NB_state_idle; - + retcode = libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); - + if (retcode == LIBSSH2_FX_OK) { handle->u.file.offset += count; return count; } - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", + 0); sftp->last_errno = retcode; - + return -1; } + /* }}} */ /* {{{ libssh2_sftp_fstat_ex * Get or Set stat on a file */ -LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) +LIBSSH2_API int +libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE * handle, + LIBSSH2_SFTP_ATTRIBUTES * attrs, int setstat) { - LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; unsigned long data_len; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ - ssize_t packet_len = handle->handle_len + 13 + (setstat ? libssh2_sftp_attrsize(attrs) : 0); + ssize_t packet_len = + handle->handle_len + 13 + (setstat ? libssh2_sftp_attrsize(attrs) : 0); unsigned char *s, *data; - static const unsigned char fstat_responses[2] = { SSH_FXP_ATTRS, SSH_FXP_STATUS }; + static const unsigned char fstat_responses[2] = + { SSH_FXP_ATTRS, SSH_FXP_STATUS }; int rc; - + if (sftp->fstat_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Issuing %s command", setstat ? "set-stat" : "stat"); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Issuing %s command", + setstat ? "set-stat" : "stat"); s = sftp->fstat_packet = LIBSSH2_ALLOC(session, packet_len); if (!sftp->fstat_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FSTAT/FSETSTAT packet", 0); + 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; + + libssh2_htonu32(s, packet_len - 4); + s += 4; *(s++) = setstat ? SSH_FXP_FSETSTAT : SSH_FXP_FSTAT; sftp->fstat_request_id = sftp->request_id++; - libssh2_htonu32(s, sftp->fstat_request_id); s += 4; - libssh2_htonu32(s, handle->handle_len); s += 4; - memcpy(s, handle->handle, handle->handle_len); s += handle->handle_len; + libssh2_htonu32(s, sftp->fstat_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); } - + sftp->fstat_state = libssh2_NB_state_created; } - + if (sftp->fstat_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)sftp->fstat_packet, packet_len); + rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->fstat_packet, + packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (packet_len != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, - setstat ? (char *)"Unable to send FXP_FSETSTAT" : (char *)"Unable to send FXP_FSTAT command", 0); + } else if (packet_len != rc) { + 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, sftp->fstat_packet); sftp->fstat_packet = NULL; sftp->fstat_state = libssh2_NB_state_idle; @@ -1308,58 +1477,66 @@ LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_ } LIBSSH2_FREE(session, sftp->fstat_packet); sftp->fstat_packet = NULL; - + sftp->fstat_state = libssh2_NB_state_sent; } - - rc = libssh2_sftp_packet_requirev(sftp, 2, fstat_responses, sftp->fstat_request_id, &data, &data_len); + + rc = libssh2_sftp_packet_requirev(sftp, 2, fstat_responses, + sftp->fstat_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); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); sftp->fstat_state = libssh2_NB_state_idle; return -1; } - + sftp->fstat_state = libssh2_NB_state_idle; - + 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); + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error", 0); return -1; } } - + libssh2_sftp_bin2attr(attrs, data + 5); - + return 0; } + /* }}} */ /* {{{ libssh2_sftp_seek * Set the read/write pointer to an arbitrary position within the file */ -LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset) +LIBSSH2_API void +libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE * handle, size_t offset) { handle->u.file.offset = offset; } + /* }}} */ /* {{{ libssh2_sftp_tell * Return the current read/write pointer's offset */ -LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle) +LIBSSH2_API size_t +libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE * handle) { return handle->u.file.offset; } + /* }}} */ @@ -1367,9 +1544,10 @@ LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle) * Close a file or directory handle * Also frees handle resource and unlinks it from the SFTP structure */ -LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle) +LIBSSH2_API int +libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE * handle) { - LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_SFTP *sftp = handle->sftp; LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; unsigned long data_len, retcode; @@ -1377,32 +1555,39 @@ LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle) ssize_t packet_len = handle->handle_len + 13; unsigned char *s, *data; int rc; - + if (handle->close_state == libssh2_NB_state_idle) { _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Closing handle"); s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len); if (!handle->close_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_CLOSE packet", 0); + 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; + + libssh2_htonu32(s, packet_len - 4); + s += 4; *(s++) = SSH_FXP_CLOSE; handle->close_request_id = sftp->request_id++; - libssh2_htonu32(s, handle->close_request_id); s += 4; - libssh2_htonu32(s, handle->handle_len); s += 4; - memcpy(s, handle->handle, handle->handle_len); s += handle->handle_len; - + libssh2_htonu32(s, handle->close_request_id); + s += 4; + libssh2_htonu32(s, handle->handle_len); + s += 4; + memcpy(s, handle->handle, handle->handle_len); + s += handle->handle_len; + handle->close_state = libssh2_NB_state_created; } - + if (handle->close_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)handle->close_packet, packet_len); + rc = libssh2_channel_write_ex(channel, 0, + (char *) handle->close_packet, + packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (packet_len != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_CLOSE command", 0); + } else if (packet_len != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_CLOSE command", 0); LIBSSH2_FREE(session, handle->close_packet); handle->close_packet = NULL; handle->close_state = libssh2_NB_state_idle; @@ -1410,52 +1595,57 @@ LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle) } LIBSSH2_FREE(session, handle->close_packet); handle->close_packet = NULL; - + handle->close_state = libssh2_NB_state_sent; } - + if (handle->close_state == libssh2_NB_state_sent) { - rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, handle->close_request_id, &data, &data_len); + rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, + handle->close_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); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); handle->close_state = libssh2_NB_state_idle; return -1; } - + handle->close_state = libssh2_NB_state_sent1; } - + 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); + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error", 0); handle->close_state = libssh2_NB_state_idle; 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) { + + if ((handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR) + && handle->u.dir.names_left) { LIBSSH2_FREE(session, handle->u.dir.names_packet); } - + handle->close_state = libssh2_NB_state_idle; - + LIBSSH2_FREE(session, handle->handle); LIBSSH2_FREE(session, handle); - + return 0; } + /* }}} */ /* ********************** @@ -1466,7 +1656,9 @@ LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle) * Delete a file from the remote server */ /* libssh2_sftp_unlink_ex - NB-UNSAFE?? */ -LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, unsigned int filename_len) +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; @@ -1475,32 +1667,39 @@ LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, ssize_t packet_len = filename_len + 13; unsigned char *s, *data; int rc; - + if (sftp->unlink_state == libssh2_NB_state_idle) { _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Unlinking %s", filename); s = sftp->unlink_packet = LIBSSH2_ALLOC(session, packet_len); if (!sftp->unlink_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_REMOVE packet", 0); + 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; + + libssh2_htonu32(s, packet_len - 4); + s += 4; *(s++) = SSH_FXP_REMOVE; sftp->unlink_request_id = sftp->request_id++; - libssh2_htonu32(s, sftp->unlink_request_id); s += 4; - libssh2_htonu32(s, filename_len); s += 4; - memcpy(s, filename, filename_len); s += filename_len; - + libssh2_htonu32(s, sftp->unlink_request_id); + s += 4; + libssh2_htonu32(s, filename_len); + s += 4; + memcpy(s, filename, filename_len); + s += filename_len; + sftp->unlink_state = libssh2_NB_state_created; } - + if (sftp->unlink_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)sftp->unlink_packet, packet_len); + rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->unlink_packet, + packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (packet_len != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_REMOVE command", 0); + } else if (packet_len != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_REMOVE command", 0); LIBSSH2_FREE(session, sftp->unlink_packet); sftp->unlink_packet = NULL; sftp->unlink_state = libssh2_NB_state_idle; @@ -1508,86 +1707,108 @@ LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, } LIBSSH2_FREE(session, sftp->unlink_packet); sftp->unlink_packet = NULL; - + sftp->unlink_state = libssh2_NB_state_sent; } - - rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->unlink_request_id, &data, &data_len); + + rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->unlink_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); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); sftp->unlink_state = libssh2_NB_state_idle; return -1; } - + sftp->unlink_state = libssh2_NB_state_idle; - + 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); + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error", 0); return -1; } } + /* }}} */ /* {{{ libssh2_sftp_rename_ex * Rename a file on the remote server */ -LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, unsigned int source_filename_len, - const char *dest_filename, unsigned int dest_filename_len, long flags) +LIBSSH2_API int +libssh2_sftp_rename_ex(LIBSSH2_SFTP * sftp, const char *source_filename, + unsigned int source_filename_len, + 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; - ssize_t packet_len = source_filename_len + dest_filename_len + 17 + (sftp->version >= 5 ? 4 : 0); + 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+) */ + source_filename_len(4) + dest_filename_len(4) + flags(4){SFTP5+) */ unsigned char *data; int rc; - + if (sftp->version < 2) { - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "Server does not support RENAME", 0); + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Server does not support RENAME", 0); return -1; } - + if (sftp->rename_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Renaming %s to %s", source_filename, dest_filename); - sftp->rename_s = sftp->rename_packet = LIBSSH2_ALLOC(session, packet_len); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Renaming %s to %s", + source_filename, dest_filename); + sftp->rename_s = sftp->rename_packet = + LIBSSH2_ALLOC(session, packet_len); if (!sftp->rename_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_RENAME packet", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_RENAME packet", + 0); return -1; } - - libssh2_htonu32(sftp->rename_s, packet_len - 4); sftp->rename_s += 4; + + libssh2_htonu32(sftp->rename_s, packet_len - 4); + sftp->rename_s += 4; *(sftp->rename_s++) = SSH_FXP_RENAME; sftp->rename_request_id = sftp->request_id++; - libssh2_htonu32(sftp->rename_s, sftp->rename_request_id); sftp->rename_s += 4; - libssh2_htonu32(sftp->rename_s, source_filename_len); sftp->rename_s += 4; - memcpy(sftp->rename_s, source_filename, source_filename_len); sftp->rename_s += source_filename_len; - libssh2_htonu32(sftp->rename_s, dest_filename_len); sftp->rename_s += 4; - memcpy(sftp->rename_s, dest_filename, dest_filename_len); sftp->rename_s += dest_filename_len; - + libssh2_htonu32(sftp->rename_s, sftp->rename_request_id); + sftp->rename_s += 4; + libssh2_htonu32(sftp->rename_s, source_filename_len); + sftp->rename_s += 4; + memcpy(sftp->rename_s, source_filename, source_filename_len); + sftp->rename_s += source_filename_len; + libssh2_htonu32(sftp->rename_s, dest_filename_len); + sftp->rename_s += 4; + memcpy(sftp->rename_s, dest_filename, dest_filename_len); + sftp->rename_s += dest_filename_len; + if (sftp->version >= 5) { - libssh2_htonu32(sftp->rename_s, flags); sftp->rename_s += 4; + libssh2_htonu32(sftp->rename_s, flags); + sftp->rename_s += 4; } - + sftp->rename_state = libssh2_NB_state_created; } - + if (sftp->rename_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)sftp->rename_packet, sftp->rename_s - sftp->rename_packet); + rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->rename_packet, + sftp->rename_s - sftp->rename_packet); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (packet_len != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_RENAME command", 0); + } else if (packet_len != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_RENAME command", 0); LIBSSH2_FREE(session, sftp->rename_packet); sftp->rename_packet = NULL; sftp->rename_state = libssh2_NB_state_idle; @@ -1595,57 +1816,65 @@ LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_fi } LIBSSH2_FREE(session, sftp->rename_packet); sftp->rename_packet = NULL; - + sftp->rename_state = libssh2_NB_state_sent; } - - rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->rename_request_id, &data, &data_len); + + rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->rename_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); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); sftp->rename_state = libssh2_NB_state_idle; return -1; } - + sftp->rename_state = libssh2_NB_state_idle; 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; + 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; } + /* }}} */ /* {{{ libssh2_sftp_mkdir_ex * Create an SFTP directory */ -LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len, long mode) +LIBSSH2_API int +libssh2_sftp_mkdir_ex(LIBSSH2_SFTP * sftp, const char *path, + unsigned int path_len, long mode) { LIBSSH2_CHANNEL *channel = sftp->channel; LIBSSH2_SESSION *session = channel->session; @@ -1657,40 +1886,47 @@ LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsi ssize_t packet_len = path_len + 13 + libssh2_sftp_attrsize(&attrs); unsigned char *packet, *s, *data; int rc; - + if (sftp->mkdir_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Creating directory %s with mode 0%lo", path, mode); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, + "Creating directory %s with mode 0%lo", path, mode); s = packet = LIBSSH2_ALLOC(session, packet_len); if (!packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_MKDIR packet", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_MKDIR packet", 0); return -1; } /* Filetype in SFTP 3 and earlier */ attrs.permissions = mode | LIBSSH2_SFTP_ATTR_PFILETYPE_DIR; - - libssh2_htonu32(s, packet_len - 4); s += 4; + + libssh2_htonu32(s, packet_len - 4); + s += 4; *(s++) = SSH_FXP_MKDIR; 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; + libssh2_htonu32(s, request_id); + s += 4; + libssh2_htonu32(s, path_len); + s += 4; + memcpy(s, path, path_len); + s += path_len; s += libssh2_sftp_attr2bin(s, &attrs); - + sftp->mkdir_state = libssh2_NB_state_created; } else { packet = sftp->mkdir_packet; request_id = sftp->mkdir_request_id; } - + if (sftp->mkdir_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)packet, packet_len); + rc = libssh2_channel_write_ex(channel, 0, (char *) packet, packet_len); if (rc == PACKET_EAGAIN) { sftp->mkdir_packet = packet; sftp->mkdir_request_id = request_id; return PACKET_EAGAIN; } if (packet_len != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_READ command", 0); + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_READ command", 0); LIBSSH2_FREE(session, packet); sftp->mkdir_state = libssh2_NB_state_idle; return -1; @@ -1699,37 +1935,42 @@ LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsi sftp->mkdir_state = libssh2_NB_state_sent; sftp->mkdir_packet = NULL; } - - rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, request_id, &data, &data_len); + + 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); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); sftp->mkdir_state = libssh2_NB_state_idle; return -1; } - + sftp->mkdir_state = libssh2_NB_state_idle; - + retcode = libssh2_ntohu32(data + 5); LIBSSH2_FREE(session, data); - + if (retcode == LIBSSH2_FX_OK) { return 0; } else { - libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, "SFTP Protocol Error", 0); + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error", 0); sftp->last_errno = retcode; return -1; } } + /* }}} */ /* {{{ libssh2_sftp_rmdir_ex * Remove a directory */ /* libssh2_sftp_rmdir_ex - NB-UNSAFE?? */ -LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsigned int path_len) +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; @@ -1738,32 +1979,39 @@ LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsi ssize_t packet_len = path_len + 13; unsigned char *s, *data; int rc; - + if (sftp->rmdir_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Removing directory: %s", path); + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "Removing directory: %s", + path); s = sftp->rmdir_packet = LIBSSH2_ALLOC(session, packet_len); if (!sftp->rmdir_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_MKDIR packet", 0); + 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; + + libssh2_htonu32(s, packet_len - 4); + s += 4; *(s++) = SSH_FXP_RMDIR; sftp->rmdir_request_id = sftp->request_id++; - libssh2_htonu32(s, sftp->rmdir_request_id); s += 4; - libssh2_htonu32(s, path_len); s += 4; - memcpy(s, path, path_len); s += path_len; - + libssh2_htonu32(s, sftp->rmdir_request_id); + s += 4; + libssh2_htonu32(s, path_len); + s += 4; + memcpy(s, path, path_len); + s += path_len; + sftp->rmdir_state = libssh2_NB_state_created; } - + if (sftp->rmdir_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)sftp->rmdir_packet, packet_len); + rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->rmdir_packet, + packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (packet_len != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send FXP_MKDIR command", 0); + } else if (packet_len != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_MKDIR command", 0); LIBSSH2_FREE(session, sftp->rmdir_packet); sftp->rmdir_packet = NULL; sftp->rmdir_state = libssh2_NB_state_idle; @@ -1771,16 +2019,17 @@ LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsi } LIBSSH2_FREE(session, sftp->rmdir_packet); sftp->rmdir_packet = NULL; - + sftp->rmdir_state = libssh2_NB_state_sent; } - - rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->rmdir_request_id, &data, &data_len); + + rc = libssh2_sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->rmdir_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); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); sftp->rmdir_state = libssh2_NB_state_idle; return -1; } @@ -1789,75 +2038,90 @@ LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, unsi 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); + libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error", 0); return -1; } } + /* }}} */ /* {{{ libssh2_sftp_stat_ex * Stat a file or symbolic link */ /* 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_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; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ - ssize_t packet_len = path_len + 13 + ((stat_type == LIBSSH2_SFTP_SETSTAT) ? libssh2_sftp_attrsize(attrs) : 0); + ssize_t packet_len = + path_len + 13 + + ((stat_type == + LIBSSH2_SFTP_SETSTAT) ? libssh2_sftp_attrsize(attrs) : 0); unsigned char *s, *data; - static const unsigned char stat_responses[2] = { SSH_FXP_ATTRS, SSH_FXP_STATUS }; + static const unsigned char stat_responses[2] = + { SSH_FXP_ATTRS, SSH_FXP_STATUS }; int rc; - + if (sftp->stat_state == libssh2_NB_state_idle) { - _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%s %s", + _libssh2_debug(session, LIBSSH2_DBG_SFTP, "%s %s", (stat_type == LIBSSH2_SFTP_SETSTAT) ? "Set-statting" : - (stat_type == LIBSSH2_SFTP_LSTAT ? "LStatting" : "Statting"), path); + (stat_type == + LIBSSH2_SFTP_LSTAT ? "LStatting" : "Statting"), path); s = sftp->stat_packet = LIBSSH2_ALLOC(session, packet_len); if (!sftp->stat_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for FXP_MKDIR packet", 0); + 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; + + 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; + 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; } sftp->stat_request_id = sftp->request_id++; - libssh2_htonu32(s, sftp->stat_request_id); s += 4; - libssh2_htonu32(s, path_len); s += 4; - memcpy(s, path, path_len); s += path_len; + libssh2_htonu32(s, sftp->stat_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); } - + sftp->stat_state = libssh2_NB_state_created; } - + if (sftp->stat_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)sftp->stat_packet, packet_len); + rc = libssh2_channel_write_ex(channel, 0, (char *) sftp->stat_packet, + packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (packet_len != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send STAT/LSTAT/SETSTAT command", 0); + } else if (packet_len != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send STAT/LSTAT/SETSTAT command", 0); LIBSSH2_FREE(session, sftp->stat_packet); sftp->stat_packet = NULL; sftp->stat_state = libssh2_NB_state_idle; @@ -1865,108 +2129,129 @@ LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, unsig } LIBSSH2_FREE(session, sftp->stat_packet); sftp->stat_packet = NULL; - + sftp->stat_state = libssh2_NB_state_sent; } - - rc = libssh2_sftp_packet_requirev(sftp, 2, stat_responses, sftp->stat_request_id, &data, &data_len); + + rc = libssh2_sftp_packet_requirev(sftp, 2, stat_responses, + sftp->stat_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); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); sftp->stat_state = libssh2_NB_state_idle; return -1; } - + sftp->stat_state = libssh2_NB_state_idle; 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); + 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; } + /* }}} */ /* {{{ libssh2_sftp_symlink_ex * Read or set a symlink */ -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_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, link_len; /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ - ssize_t packet_len = path_len + 13 + ((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0); + ssize_t packet_len = + path_len + 13 + + ((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0); unsigned char *s, *data; - static const unsigned char link_responses[2] = { SSH_FXP_NAME, SSH_FXP_STATUS }; + 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); + + 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; } - + if (sftp->symlink_state == libssh2_NB_state_idle) { s = sftp->symlink_packet = LIBSSH2_ALLOC(session, packet_len); if (!sftp->symlink_packet) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for SYMLINK/READLINK/REALPATH packet", 0); + 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; + + _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; + 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; } sftp->symlink_request_id = sftp->request_id++; - libssh2_htonu32(s, sftp->symlink_request_id); s += 4; - libssh2_htonu32(s, path_len); s += 4; - memcpy(s, path, path_len); s += path_len; + libssh2_htonu32(s, sftp->symlink_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; + libssh2_htonu32(s, target_len); + s += 4; + memcpy(s, target, target_len); + s += target_len; } - + sftp->symlink_state = libssh2_NB_state_created; } - + if (sftp->symlink_state == libssh2_NB_state_created) { - rc = libssh2_channel_write_ex(channel, 0, (char *)sftp->symlink_packet, packet_len); + rc = libssh2_channel_write_ex(channel, 0, + (char *) sftp->symlink_packet, + packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (packet_len != rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send SYMLINK/READLINK command", 0); + } else if (packet_len != rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send SYMLINK/READLINK command", 0); LIBSSH2_FREE(session, sftp->symlink_packet); sftp->symlink_packet = NULL; sftp->symlink_state = libssh2_NB_state_idle; @@ -1974,42 +2259,47 @@ LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, un } LIBSSH2_FREE(session, sftp->symlink_packet); sftp->symlink_packet = NULL; - + sftp->symlink_state = libssh2_NB_state_sent; } - - rc = libssh2_sftp_packet_requirev(sftp, 2, link_responses, sftp->symlink_request_id, &data, &data_len); + + rc = libssh2_sftp_packet_requirev(sftp, 2, link_responses, + sftp->symlink_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); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for status message", 0); sftp->symlink_state = libssh2_NB_state_idle; return -1; } - + sftp->symlink_state = libssh2_NB_state_idle; 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); + 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_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; @@ -2017,16 +2307,19 @@ LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, un memcpy(target, data + 13, link_len); target[link_len] = 0; LIBSSH2_FREE(session, data); - + return link_len; } + /* }}} */ /* {{{ libssh2_sftp_last_error * Returns the last error code reported by SFTP */ -LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp) +LIBSSH2_API unsigned long +libssh2_sftp_last_error(LIBSSH2_SFTP * sftp) { return sftp->last_errno; } + /* }}} */ diff --git a/src/transport.c b/src/transport.c index dc22b9b..bc83f7c 100644 --- a/src/transport.c +++ b/src/transport.c @@ -43,47 +43,47 @@ #include -#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */ -#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */ +#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */ +#define MAX_MACSIZE 20 /* MUST fit biggest MAC length we support */ #ifdef LIBSSH2DEBUG #define UNPRINTABLE_CHAR '.' -static void debugdump(LIBSSH2_SESSION *session, - const char *desc, unsigned char *ptr, - unsigned long size) +static void +debugdump(LIBSSH2_SESSION * session, + const char *desc, unsigned char *ptr, unsigned long size) { - size_t i; - size_t c; - FILE *stream = stdout; - unsigned int width=0x10; + size_t i; + size_t c; + FILE *stream = stdout; + unsigned int width = 0x10; - if (!(session->showmask & (1<< LIBSSH2_DBG_TRANS))) { - /* not asked for, bail out */ - return; - } - - fprintf(stream, "=> %s (%d bytes)\n", desc, (int)size); - - for(i=0; ishowmask & (1 << LIBSSH2_DBG_TRANS))) { + /* not asked for, bail out */ + return; } - 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, "=> %s (%d bytes)\n", desc, (int) size); + + for(i = 0; i < size; i += width) { + + fprintf(stream, "%04lx: ", (long)i); + + /* hex not disabled, show it */ + for(c = 0; c < width; c++) { + 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); + } + fputc('\n', stream); /* newline */ } - fputc('\n', stream); /* newline */ - } - fflush(stream); + fflush(stream); } #else #define debugdump(a,x,y,z) @@ -95,35 +95,36 @@ static void debugdump(LIBSSH2_SESSION *session, * returns PACKET_NONE on success and PACKET_FAIL on failure */ -static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source, - unsigned char *dest, int len) +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 */ + we risk losing those extra bytes */ assert((len % blocksize) == 0); - - while(len >= blocksize) { + + 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); + (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 */ + + len -= blocksize; /* less bytes left */ + dest += blocksize; /* advance write pointer */ + source += blocksize; /* advance read pointer */ } - return PACKET_NONE; /* all is fine */ + return PACKET_NONE; /* all is fine */ } /* @@ -131,26 +132,26 @@ static libssh2pack_t decrypt(LIBSSH2_SESSION *session, unsigned char *source, * collected. */ static libssh2pack_t -fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */) +fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ ) { unsigned char macbuf[MAX_MACSIZE]; struct transportpacket *p = &session->packet; int rc; - + if (session->fullpacket_state == libssh2_NB_state_idle) { session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED; - session->fullpacket_payload_len = p->packet_length-1; - + session->fullpacket_payload_len = p->packet_length - 1; + if (encrypted) { - + /* Calculate MAC hash */ - session->remote.mac->hash(session, - macbuf, /* store hash here */ + session->remote.mac->hash(session, macbuf, /* store hash here */ session->remote.seqno, p->init, 5, - p->payload, session->fullpacket_payload_len, + p->payload, + session->fullpacket_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 @@ -161,55 +162,53 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */) session->fullpacket_macstate = LIBSSH2_MAC_INVALID; } } - + session->remote.seqno++; - + /* ignore the padding */ session->fullpacket_payload_len -= p->padding_length; - + /* Check for and deal with decompression */ - if (session->remote.comp && - strcmp(session->remote.comp->name, "none")) { + 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, session->fullpacket_payload_len, + p->payload, + session->fullpacket_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; session->fullpacket_payload_len = data_len; - } - else { + } else { if (data == p->payload) { /* It's not to be freed, because the * compression layer reused payload, So let's * do the same! */ session->fullpacket_payload_len = data_len; - } - else { + } 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); + 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); @@ -217,27 +216,28 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */) } } } - + session->fullpacket_packet_type = p->payload[0]; - + debugdump(session, "libssh2_packet_read() plain", p->payload, session->fullpacket_payload_len); - + session->fullpacket_state = libssh2_NB_state_created; } - + if (session->fullpacket_state == libssh2_NB_state_created) { - rc = libssh2_packet_add(session, p->payload, session->fullpacket_payload_len, session->fullpacket_macstate); + rc = libssh2_packet_add(session, p->payload, + session->fullpacket_payload_len, + session->fullpacket_macstate); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc < 0) { + } else if (rc < 0) { return PACKET_FAIL; } } - + session->fullpacket_state = libssh2_NB_state_idle; - + return session->fullpacket_packet_type; } @@ -256,7 +256,8 @@ fullpacket(LIBSSH2_SESSION *session, int encrypted /* 1 or 0 */) * This function reads the binary stream as specified in chapter 6 of RFC4253 * "The Secure Shell (SSH) Transport Layer Protocol" */ -libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) +libssh2pack_t +libssh2_packet_read(LIBSSH2_SESSION * session) { libssh2pack_t rc; struct transportpacket *p = &session->packet; @@ -268,7 +269,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) int blocksize; int minimum; int encrypted = 1; - + /* * =============================== NOTE =============================== * I know this is very ugly and not a really good use of "goto", but @@ -279,39 +280,39 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) encrypted = session->readPack_encrypted; goto libssh2_packet_read_point1; } - + 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 */ + 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); - + if (remainbuf < minimum) { /* If we have less than a minimum left, it 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) { @@ -322,10 +323,12 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) /* 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)); + 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 @@ -339,30 +342,30 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) &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 (numbytes < blocksize) { /* we can't act on anything less than blocksize */ return PACKET_EAGAIN; } - + 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 + /* 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 { @@ -370,20 +373,22 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) 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 + + /* 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); - + 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 @@ -395,7 +400,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) 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); @@ -404,40 +409,40 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) } /* 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 */ + 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 + /* 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 */ @@ -449,10 +454,10 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) frac = numdecrypt % blocksize; if (frac) { /* not an aligned amount of blocks, - align it */ + align it */ numdecrypt -= frac; /* and make it no unencrypted data - after it */ + after it */ numbytes = 0; } } @@ -460,7 +465,7 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) /* 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 */ @@ -468,23 +473,23 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) 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 */ @@ -492,68 +497,71 @@ libssh2pack_t libssh2_packet_read(LIBSSH2_SESSION *session) /* 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 */ -libssh2_packet_read_point1: + libssh2_packet_read_point1: rc = fullpacket(session, encrypted); if (rc == PACKET_EAGAIN) { session->readPack_encrypted = encrypted; session->readPack_state = libssh2_NB_state_jump1; return PACKET_EAGAIN; } - - p->total_num = 0; /* no packet buffer available */ - + + p->total_num = 0; /* no packet buffer available */ + return rc; } - } while (1); /* loop */ + } while (1); /* loop */ - return PACKET_FAIL; /* we never reach this point */ + return PACKET_FAIL; /* we never reach this point */ } + /* }}} */ #ifndef OLDSEND -static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len, ssize_t *ret) +static libssh2pack_t +send_existing(LIBSSH2_SESSION * session, unsigned char *data, + 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 + /* 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 + 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 */ - + + *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)); - + + 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) { + } else if (rc < 0) { /* nothing was sent */ if (errno != EAGAIN) { /* send failure! */ @@ -561,10 +569,11 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data } return PACKET_EAGAIN; } - - debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent], length); - p->osent += length; /* we sent away this much data */ - + + debugdump(session, "libssh2_packet_write send()", &p->outbuf[p->osent], + length); + p->osent += length; /* we sent away this much data */ + return PACKET_NONE; } @@ -577,16 +586,20 @@ static libssh2pack_t send_existing(LIBSSH2_SESSION *session, unsigned char *data * sent, and this function should then be called with the same argument set * (same data pointer and same data_len) until zero or failure is returned. */ -int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned long data_len) +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 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 free_data = 0; #ifdef RANDOM_PADDING int rand_max; - int seed = data[0]; /* FIXME: make this random */ + int seed = data[0]; /* FIXME: make this random */ #endif struct transportpacket *p = &session->packet; int encrypted; @@ -595,41 +608,42 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned 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; - + + 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 */ + 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 */ - + + 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) */ @@ -639,19 +653,20 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned #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; + 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); - + 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. */ @@ -659,7 +674,7 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned 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); @@ -672,51 +687,54 @@ int libssh2_packet_write(LIBSSH2_SESSION *session, unsigned char *data, unsigned 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); - + 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) { + 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 */ + 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, + + 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))) { + 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->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_NONE; /* all is good */ } /* }}} */ diff --git a/src/userauth.c b/src/userauth.c index 3d1db47..91151f6 100644 --- a/src/userauth.c +++ b/src/userauth.c @@ -52,50 +52,64 @@ * Not a common configuration for any SSH server though * username should be NULL, or a null terminated string */ -LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *username, unsigned int username_len) +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 }; + static const unsigned char reply_codes[3] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; /* 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 *s; int rc; - + if (session->userauth_list_state == libssh2_NB_state_idle) { /* Zero the whole thing out */ - memset(&session->userauth_list_packet_requirev_state, 0, sizeof(session->userauth_list_packet_requirev_state)); - + memset(&session->userauth_list_packet_requirev_state, 0, + sizeof(session->userauth_list_packet_requirev_state)); + session->userauth_list_data_len = username_len + 31; - - s = session->userauth_list_data = LIBSSH2_ALLOC(session, session->userauth_list_data_len); + + s = session->userauth_list_data = + LIBSSH2_ALLOC(session, session->userauth_list_data_len); if (!session->userauth_list_data) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth_list", 0); + 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; + libssh2_htonu32(s, username_len); + s += 4; if (username) { - memcpy(s, username, username_len); s += username_len; + 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; - session->userauth_list_state = libssh2_NB_state_created; } if (session->userauth_list_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, session->userauth_list_data, session->userauth_list_data_len); + rc = libssh2_packet_write(session, session->userauth_list_data, + session->userauth_list_data_len); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting userauth list", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list", 0); return NULL; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-none request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-none request", 0); LIBSSH2_FREE(session, session->userauth_list_data); session->userauth_list_data = NULL; session->userauth_list_state = libssh2_NB_state_idle; @@ -103,18 +117,22 @@ LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *us } LIBSSH2_FREE(session, session->userauth_list_data); session->userauth_list_data = NULL; - + session->userauth_list_state = libssh2_NB_state_sent; } if (session->userauth_list_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &session->userauth_list_data, &session->userauth_list_data_len, - 0, NULL, 0, &session->userauth_list_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, + &session->userauth_list_data, + &session->userauth_list_data_len, 0, + NULL, 0, + &session-> + userauth_list_packet_requirev_state); if (rc == PACKET_EAGAIN) { - libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block requesting userauth list", 0); + libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list", 0); return NULL; - } - else if (rc) { + } else if (rc) { libssh2_error(session, LIBSSH2_ERROR_NONE, "No error", 0); session->userauth_list_state = libssh2_NB_state_idle; return NULL; @@ -131,83 +149,107 @@ LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, const char *us } methods_len = libssh2_ntohu32(session->userauth_list_data + 1); - memcpy(session->userauth_list_data, session->userauth_list_data + 5, methods_len); + memcpy(session->userauth_list_data, session->userauth_list_data + 5, + methods_len); session->userauth_list_data[methods_len] = '\0'; - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s", session->userauth_list_data); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Permitted auth methods: %s", + session->userauth_list_data); } - + session->userauth_list_state = libssh2_NB_state_idle; - return (char *)session->userauth_list_data; + return (char *) session->userauth_list_data; } + /* }}} */ /* {{{ libssh2_userauth_authenticated * 0 if not yet authenticated * non-zero is already authenticated */ -LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session) +LIBSSH2_API int +libssh2_userauth_authenticated(LIBSSH2_SESSION * session) { return session->state & LIBSSH2_STATE_AUTHENTICATED; } + /* }}} */ /* {{{ libssh2_userauth_password * 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))) +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))) { unsigned char *s; - static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, - SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 }; + static const unsigned char reply_codes[4] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 + }; int rc; - + if (session->userauth_pswd_state == libssh2_NB_state_idle) { /* Zero the whole thing out */ - memset(&session->userauth_pswd_packet_requirev_state, 0, sizeof(session->userauth_pswd_packet_requirev_state)); + memset(&session->userauth_pswd_packet_requirev_state, 0, + sizeof(session->userauth_pswd_packet_requirev_state)); /* * 40 = acket_type(1) + username_len(4) + service_len(4) + * service(14)"ssh-connection" + method_len(4) + method(8)"password" + * chgpwdbool(1) + password_len(4) */ session->userauth_pswd_data_len = username_len + password_len + 40; - + session->userauth_pswd_data0 = ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ; - - s = session->userauth_pswd_data = LIBSSH2_ALLOC(session, session->userauth_pswd_data_len); + + s = session->userauth_pswd_data = + LIBSSH2_ALLOC(session, session->userauth_pswd_data_len); if (!session->userauth_pswd_data) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth-password request", 0); + 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; + 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"); - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting to login using password authentication"); - session->userauth_pswd_state = libssh2_NB_state_created; } - + if (session->userauth_pswd_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, session->userauth_pswd_data, session->userauth_pswd_data_len); + rc = libssh2_packet_write(session, session->userauth_pswd_data, + session->userauth_pswd_data_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-password request", 0); LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; session->userauth_pswd_state = libssh2_NB_state_idle; @@ -215,105 +257,140 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, uns } LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; - + session->userauth_pswd_state = libssh2_NB_state_sent; } - password_response: - - if ((session->userauth_pswd_state == libssh2_NB_state_sent) || (session->userauth_pswd_state == libssh2_NB_state_sent1) || - (session->userauth_pswd_state == libssh2_NB_state_sent2)) { + password_response: + + if ((session->userauth_pswd_state == libssh2_NB_state_sent) + || (session->userauth_pswd_state == libssh2_NB_state_sent1) + || (session->userauth_pswd_state == libssh2_NB_state_sent2)) { if (session->userauth_pswd_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &session->userauth_pswd_data, &session->userauth_pswd_data_len, - 0, NULL, 0, &session->userauth_pswd_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, + &session->userauth_pswd_data, + &session->userauth_pswd_data_len, + 0, NULL, 0, + &session-> + userauth_pswd_packet_requirev_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { session->userauth_pswd_state = libssh2_NB_state_idle; return -1; } if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password authentication successful"); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, + "Password authentication successful"); LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; session->state |= LIBSSH2_STATE_AUTHENTICATED; session->userauth_pswd_state = libssh2_NB_state_idle; return 0; } - + session->userauth_pswd_newpw = NULL; session->userauth_pswd_newpw_len = 0; - + session->userauth_pswd_state = libssh2_NB_state_sent1; } - - if ((session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) || - (session->userauth_pswd_data0 == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)) { + + if ((session->userauth_pswd_data[0] == + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) + || (session->userauth_pswd_data0 == + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)) { session->userauth_pswd_data0 = SSH_MSG_USERAUTH_PASSWD_CHANGEREQ; - + if ((session->userauth_pswd_state == libssh2_NB_state_sent1) || (session->userauth_pswd_state == libssh2_NB_state_sent2)) { if (session->userauth_pswd_state == libssh2_NB_state_sent1) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Password change required"); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, + "Password change required"); LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; } if (passwd_change_cb) { if (session->userauth_pswd_state == libssh2_NB_state_sent1) { - passwd_change_cb(session, &session->userauth_pswd_newpw, &session->userauth_pswd_newpw_len, + passwd_change_cb(session, + &session->userauth_pswd_newpw, + &session->userauth_pswd_newpw_len, &session->abstract); if (!session->userauth_pswd_newpw) { - libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password expired, and callback failed", 0); + libssh2_error(session, + LIBSSH2_ERROR_PASSWORD_EXPIRED, + "Password expired, and callback failed", + 0); return -1; } - + /* basic data_len + newpw_len(4) */ - session->userauth_pswd_data_len = username_len + password_len + 44 + session->userauth_pswd_newpw_len; - - s = session->userauth_pswd_data = LIBSSH2_ALLOC(session, session->userauth_pswd_data_len); + session->userauth_pswd_data_len = + username_len + password_len + 44 + + session->userauth_pswd_newpw_len; + + s = session->userauth_pswd_data = + LIBSSH2_ALLOC(session, + session->userauth_pswd_data_len); if (!session->userauth_pswd_data) { libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate memory for userauth-password-change request", 0); - LIBSSH2_FREE(session, session->userauth_pswd_newpw); + "Unable to allocate memory for userauth-password-change request", + 0); + LIBSSH2_FREE(session, + session->userauth_pswd_newpw); session->userauth_pswd_newpw = NULL; return -1; } *(s++) = SSH_MSG_USERAUTH_REQUEST; - libssh2_htonu32(s, username_len); s += 4; - memcpy(s, username, username_len); s += username_len; + 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 = 0x01; s++; + *s = 0x01; + 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, session->userauth_pswd_newpw_len); + s += 4; + memcpy(s, session->userauth_pswd_newpw, + session->userauth_pswd_newpw_len); + s += session->userauth_pswd_newpw_len; - libssh2_htonu32(s, session->userauth_pswd_newpw_len); s += 4; - memcpy(s, session->userauth_pswd_newpw, session->userauth_pswd_newpw_len); - s += session->userauth_pswd_newpw_len; - session->userauth_pswd_state = libssh2_NB_state_sent2; } if (session->userauth_pswd_state == libssh2_NB_state_sent2) { - rc = libssh2_packet_write(session, session->userauth_pswd_data, session->userauth_pswd_data_len); + rc = libssh2_packet_write(session, + session->userauth_pswd_data, + session-> + userauth_pswd_data_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, - "Unable to send userauth-password-change request", 0); + "Unable to send userauth-password-change request", + 0); LIBSSH2_FREE(session, session->userauth_pswd_data); session->userauth_pswd_data = NULL; - LIBSSH2_FREE(session, session->userauth_pswd_newpw); + LIBSSH2_FREE(session, + session->userauth_pswd_newpw); session->userauth_pswd_newpw = NULL; return -1; } @@ -331,7 +408,9 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, uns } } } else { - libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password Expired, and no callback specified", 0); + libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, + "Password Expired, and no callback specified", + 0); session->userauth_pswd_state = libssh2_NB_state_idle; return -1; } @@ -344,14 +423,18 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, uns session->userauth_pswd_state = libssh2_NB_state_idle; return -1; } + /* }}} */ /* {{{ libssh2_file_read_publickey * 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) +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) { FILE *fd; char c; @@ -359,34 +442,40 @@ libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char **method, un size_t pubkey_len = 0; unsigned int tmp_len; - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Loading public key file: %s", pubkeyfile); + _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); + 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++; + 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); + 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); + 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_error(session, LIBSSH2_ERROR_FILE, + "Unable to read public key from file", 0); LIBSSH2_FREE(session, pubkey); fclose(fd); return -1; @@ -395,16 +484,19 @@ libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char **method, un /* * Remove trailing whitespace */ - while (pubkey_len && isspace(pubkey[pubkey_len-1])) pubkey_len--; + 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_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_error(session, LIBSSH2_ERROR_FILE, "Invalid public key data", + 0); LIBSSH2_FREE(session, pubkey); return -1; } @@ -421,8 +513,10 @@ libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char **method, un 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); + 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; } @@ -431,64 +525,88 @@ libssh2_file_read_publickey(LIBSSH2_SESSION *session, unsigned char **method, un 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) +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); + _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) { + 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); + libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No handler for specified private key", 0); return -1; } - if ((*hostkey_method)->initPEM(session, privkeyfile, (unsigned char *)passphrase, hostkey_abstract)) { - libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to initialize private key from file", 0); + if ((*hostkey_method)-> + initPEM(session, privkeyfile, (unsigned char *) passphrase, + hostkey_abstract)) { + libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to initialize private key from file", 0); return -1; } return 0; -} +} + /* }}} */ /* {{{ libssh2_userauth_hostbased_fromfile_ex * Authenticate using a keypair found in the named files */ 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) +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 LIBSSH2_HOSTKEY_METHOD *privkeyobj; void *abstract; unsigned char buf[5]; struct iovec datavec[4]; unsigned char *pubkeydata, *sig; - static const unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; + static const unsigned char reply_codes[3] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; unsigned long pubkeydata_len, sig_len, data_len; int rc; if (session->userauth_host_state == libssh2_NB_state_idle) { /* Zero the whole thing out */ - memset(&session->userauth_host_packet_requirev_state, 0, sizeof(session->userauth_host_packet_requirev_state)); - - if (libssh2_file_read_publickey(session, &session->userauth_host_method, &session->userauth_host_method_len, - &pubkeydata, &pubkeydata_len, publickey)) { + memset(&session->userauth_host_packet_requirev_state, 0, + sizeof(session->userauth_host_packet_requirev_state)); + + if (libssh2_file_read_publickey + (session, &session->userauth_host_method, + &session->userauth_host_method_len, &pubkeydata, &pubkeydata_len, + publickey)) { return -1; } @@ -498,16 +616,21 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *use * authmethod(9)"hostbased" + method_len(4) + pubkeydata_len(4) + * local_username_len(4) */ - session->userauth_host_packet_len = username_len + session->userauth_host_method_len + hostname_len + + session->userauth_host_packet_len = + username_len + session->userauth_host_method_len + hostname_len + local_username_len + pubkeydata_len + 48; - + /* * 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 */ session->userauth_host_s = session->userauth_host_packet = - LIBSSH2_ALLOC(session, session->userauth_host_packet_len + 4 + (4 + session->userauth_host_method_len) +(4 + pubkeydata_len)); + LIBSSH2_ALLOC(session, + session->userauth_host_packet_len + 4 + (4 + + session-> + userauth_host_method_len) + + (4 + pubkeydata_len)); if (!session->userauth_host_packet) { LIBSSH2_FREE(session, session->userauth_host_method); session->userauth_host_method = NULL; @@ -515,30 +638,46 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *use } *(session->userauth_host_s++) = SSH_MSG_USERAUTH_REQUEST; - libssh2_htonu32(session->userauth_host_s, username_len); session->userauth_host_s += 4; - memcpy(session->userauth_host_s, username, username_len); session->userauth_host_s += username_len; + libssh2_htonu32(session->userauth_host_s, username_len); + session->userauth_host_s += 4; + memcpy(session->userauth_host_s, username, username_len); + session->userauth_host_s += username_len; - libssh2_htonu32(session->userauth_host_s, 14); session->userauth_host_s += 4; - memcpy(session->userauth_host_s, "ssh-connection", 14); session->userauth_host_s += 14; + libssh2_htonu32(session->userauth_host_s, 14); + session->userauth_host_s += 4; + memcpy(session->userauth_host_s, "ssh-connection", 14); + session->userauth_host_s += 14; - libssh2_htonu32(session->userauth_host_s, 9); session->userauth_host_s += 4; - memcpy(session->userauth_host_s, "hostbased", 9); session->userauth_host_s += 9; + libssh2_htonu32(session->userauth_host_s, 9); + session->userauth_host_s += 4; + memcpy(session->userauth_host_s, "hostbased", 9); + session->userauth_host_s += 9; - libssh2_htonu32(session->userauth_host_s, session->userauth_host_method_len); session->userauth_host_s += 4; - memcpy(session->userauth_host_s, session->userauth_host_method, session->userauth_host_method_len); - session->userauth_host_s += session->userauth_host_method_len; + libssh2_htonu32(session->userauth_host_s, + session->userauth_host_method_len); + session->userauth_host_s += 4; + memcpy(session->userauth_host_s, session->userauth_host_method, + session->userauth_host_method_len); + session->userauth_host_s += session->userauth_host_method_len; - libssh2_htonu32(session->userauth_host_s, pubkeydata_len); session->userauth_host_s += 4; - memcpy(session->userauth_host_s, pubkeydata, pubkeydata_len); session->userauth_host_s += pubkeydata_len; + libssh2_htonu32(session->userauth_host_s, pubkeydata_len); + session->userauth_host_s += 4; + memcpy(session->userauth_host_s, pubkeydata, pubkeydata_len); + session->userauth_host_s += pubkeydata_len; - libssh2_htonu32(session->userauth_host_s, hostname_len); session->userauth_host_s += 4; - memcpy(session->userauth_host_s, hostname, hostname_len); session->userauth_host_s += hostname_len; + libssh2_htonu32(session->userauth_host_s, hostname_len); + session->userauth_host_s += 4; + memcpy(session->userauth_host_s, hostname, hostname_len); + session->userauth_host_s += hostname_len; - libssh2_htonu32(session->userauth_host_s, local_username_len); session->userauth_host_s += 4; - memcpy(session->userauth_host_s, local_username, local_username_len); session->userauth_host_s += local_username_len; + libssh2_htonu32(session->userauth_host_s, local_username_len); + session->userauth_host_s += 4; + memcpy(session->userauth_host_s, local_username, local_username_len); + session->userauth_host_s += local_username_len; - if (libssh2_file_read_privatekey(session, &privkeyobj, &abstract, session->userauth_host_method, - session->userauth_host_method_len, privatekey, passphrase)) { + if (libssh2_file_read_privatekey + (session, &privkeyobj, &abstract, session->userauth_host_method, + session->userauth_host_method_len, privatekey, passphrase)) { LIBSSH2_FREE(session, session->userauth_host_method); session->userauth_host_method = NULL; LIBSSH2_FREE(session, session->userauth_host_packet); @@ -572,10 +711,11 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *use if (sig_len > pubkeydata_len) { unsigned char *newpacket; /* Should *NEVER* happen, but...well.. better safe than sorry */ - newpacket = LIBSSH2_REALLOC(session, session->userauth_host_packet, session->userauth_host_packet_len + 4 + - (4 + session->userauth_host_method_len) + (4 + sig_len)); /* PK sigblob */ + newpacket = LIBSSH2_REALLOC(session, session->userauth_host_packet, session->userauth_host_packet_len + 4 + (4 + session->userauth_host_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_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating additional space for userauth-hostbased packet", + 0); LIBSSH2_FREE(session, sig); LIBSSH2_FREE(session, session->userauth_host_packet); session->userauth_host_packet = NULL; @@ -586,33 +726,43 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *use session->userauth_host_packet = newpacket; } - session->userauth_host_s = session->userauth_host_packet + session->userauth_host_packet_len; + session->userauth_host_s = + session->userauth_host_packet + session->userauth_host_packet_len; - libssh2_htonu32(session->userauth_host_s, 4 + session->userauth_host_method_len + 4 + sig_len); - session->userauth_host_s += 4; + libssh2_htonu32(session->userauth_host_s, + 4 + session->userauth_host_method_len + 4 + sig_len); + session->userauth_host_s += 4; - libssh2_htonu32(session->userauth_host_s, session->userauth_host_method_len); session->userauth_host_s += 4; - memcpy(session->userauth_host_s, session->userauth_host_method, session->userauth_host_method_len); - session->userauth_host_s += session->userauth_host_method_len; + libssh2_htonu32(session->userauth_host_s, + session->userauth_host_method_len); + session->userauth_host_s += 4; + memcpy(session->userauth_host_s, session->userauth_host_method, + session->userauth_host_method_len); + session->userauth_host_s += session->userauth_host_method_len; LIBSSH2_FREE(session, session->userauth_host_method); session->userauth_host_method = NULL; - libssh2_htonu32(session->userauth_host_s, sig_len); session->userauth_host_s += 4; - memcpy(session->userauth_host_s, sig, sig_len); session->userauth_host_s += sig_len; + libssh2_htonu32(session->userauth_host_s, sig_len); + session->userauth_host_s += 4; + memcpy(session->userauth_host_s, sig, sig_len); + session->userauth_host_s += sig_len; LIBSSH2_FREE(session, sig); - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting hostbased authentication"); - + _libssh2_debug(session, LIBSSH2_DBG_AUTH, + "Attempting hostbased authentication"); + session->userauth_host_state = libssh2_NB_state_created; } - + if (session->userauth_host_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, session->userauth_host_packet, session->userauth_host_s - session->userauth_host_packet); + rc = libssh2_packet_write(session, session->userauth_host_packet, + session->userauth_host_s - + session->userauth_host_packet); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-hostbased request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-hostbased request", 0); LIBSSH2_FREE(session, session->userauth_host_packet); session->userauth_host_packet = NULL; session->userauth_host_state = libssh2_NB_state_idle; @@ -620,23 +770,26 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *use } LIBSSH2_FREE(session, session->userauth_host_packet); session->userauth_host_packet = NULL; - + session->userauth_host_state = libssh2_NB_state_sent; } if (session->userauth_host_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &session->userauth_host_data, &data_len, - 0, NULL, 0, &session->userauth_host_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, + &session->userauth_host_data, + &data_len, 0, NULL, 0, + &session-> + userauth_host_packet_requirev_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { session->userauth_host_state = libssh2_NB_state_idle; return -1; } if (session->userauth_host_data[0] == SSH_MSG_USERAUTH_SUCCESS) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Hostbased authentication successful"); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, + "Hostbased authentication successful"); /* We are us and we've proved it. */ LIBSSH2_FREE(session, session->userauth_host_data); session->userauth_host_data = NULL; @@ -650,34 +803,46 @@ libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, const char *use LIBSSH2_FREE(session, session->userauth_host_data); session->userauth_host_data = NULL; libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, - "Invalid signature for supplied public key, or bad username/public key combination", 0); + "Invalid signature for supplied public key, or bad username/public key combination", + 0); session->userauth_host_state = libssh2_NB_state_idle; return -1; } + /* }}} */ /* {{{ libssh2_userauth_publickey_fromfile_ex * Authenticate using a keypair found in the named files */ 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) +libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION * session, + const char *username, + unsigned int username_len, + 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 *pubkeydata, *sig; - unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PK_OK, 0 }; + unsigned char reply_codes[4] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, + SSH_MSG_USERAUTH_PK_OK, 0 + }; unsigned long pubkeydata_len, sig_len; int rc; - + if (session->userauth_pblc_state == libssh2_NB_state_idle) { /* Zero the whole thing out */ - memset(&session->userauth_pblc_packet_requirev_state, 0, sizeof(session->userauth_pblc_packet_requirev_state)); - - if (libssh2_file_read_publickey(session, &session->userauth_pblc_method, &session->userauth_pblc_method_len, - &pubkeydata, &pubkeydata_len, publickey)) { + memset(&session->userauth_pblc_packet_requirev_state, 0, + sizeof(session->userauth_pblc_packet_requirev_state)); + + if (libssh2_file_read_publickey + (session, &session->userauth_pblc_method, + &session->userauth_pblc_method_len, &pubkeydata, &pubkeydata_len, + publickey)) { return -1; } @@ -687,15 +852,21 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use * authmethod(9)"publickey" + sig_included(1)'\0' + algmethod_len(4) + * publickey_len(4) */ - session->userauth_pblc_packet_len = username_len + session->userauth_pblc_method_len + pubkeydata_len + 45; - + session->userauth_pblc_packet_len = + username_len + session->userauth_pblc_method_len + pubkeydata_len + + 45; + /* * 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 */ session->userauth_pblc_s = session->userauth_pblc_packet = - LIBSSH2_ALLOC(session, session->userauth_pblc_packet_len + 4 + (4 + session->userauth_pblc_method_len) + (4 + pubkeydata_len)); + LIBSSH2_ALLOC(session, + session->userauth_pblc_packet_len + 4 + (4 + + session-> + userauth_pblc_method_len) + + (4 + pubkeydata_len)); if (!session->userauth_pblc_packet) { LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; @@ -704,39 +875,52 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use } *(session->userauth_pblc_s++) = SSH_MSG_USERAUTH_REQUEST; - libssh2_htonu32(session->userauth_pblc_s, username_len); session->userauth_pblc_s += 4; - memcpy(session->userauth_pblc_s, username, username_len); session->userauth_pblc_s += username_len; + libssh2_htonu32(session->userauth_pblc_s, username_len); + session->userauth_pblc_s += 4; + memcpy(session->userauth_pblc_s, username, username_len); + session->userauth_pblc_s += username_len; - libssh2_htonu32(session->userauth_pblc_s, 14); session->userauth_pblc_s += 4; - memcpy(session->userauth_pblc_s, "ssh-connection", 14); session->userauth_pblc_s += 14; + libssh2_htonu32(session->userauth_pblc_s, 14); + session->userauth_pblc_s += 4; + memcpy(session->userauth_pblc_s, "ssh-connection", 14); + session->userauth_pblc_s += 14; - libssh2_htonu32(session->userauth_pblc_s, 9); session->userauth_pblc_s += 4; - memcpy(session->userauth_pblc_s, "publickey", 9); session->userauth_pblc_s += 9; + libssh2_htonu32(session->userauth_pblc_s, 9); + session->userauth_pblc_s += 4; + memcpy(session->userauth_pblc_s, "publickey", 9); + session->userauth_pblc_s += 9; session->userauth_pblc_b = session->userauth_pblc_s; /* Not sending signature with *this* packet */ *(session->userauth_pblc_s++) = 0; - libssh2_htonu32(session->userauth_pblc_s, session->userauth_pblc_method_len); session->userauth_pblc_s += 4; - memcpy(session->userauth_pblc_s, session->userauth_pblc_method, session->userauth_pblc_method_len); - session->userauth_pblc_s += session->userauth_pblc_method_len; + libssh2_htonu32(session->userauth_pblc_s, + session->userauth_pblc_method_len); + session->userauth_pblc_s += 4; + memcpy(session->userauth_pblc_s, session->userauth_pblc_method, + session->userauth_pblc_method_len); + session->userauth_pblc_s += session->userauth_pblc_method_len; - libssh2_htonu32(session->userauth_pblc_s, pubkeydata_len); session->userauth_pblc_s += 4; - memcpy(session->userauth_pblc_s, pubkeydata, pubkeydata_len); session->userauth_pblc_s += pubkeydata_len; + libssh2_htonu32(session->userauth_pblc_s, pubkeydata_len); + session->userauth_pblc_s += 4; + memcpy(session->userauth_pblc_s, pubkeydata, pubkeydata_len); + session->userauth_pblc_s += pubkeydata_len; LIBSSH2_FREE(session, pubkeydata); - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication"); - + _libssh2_debug(session, LIBSSH2_DBG_AUTH, + "Attempting publickey authentication"); + session->userauth_pblc_state = libssh2_NB_state_created; } - + if (session->userauth_pblc_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, session->userauth_pblc_packet, session->userauth_pblc_packet_len); + rc = libssh2_packet_write(session, session->userauth_pblc_packet, + session->userauth_pblc_packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-publickey request", 0); LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; LIBSSH2_FREE(session, session->userauth_pblc_method); @@ -744,17 +928,20 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use session->userauth_pblc_state = libssh2_NB_state_idle; return -1; } - + session->userauth_pblc_state = libssh2_NB_state_sent; } if (session->userauth_pblc_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &session->userauth_pblc_data, &session->userauth_pblc_data_len, 0, NULL, 0, - &session->userauth_pblc_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, + &session->userauth_pblc_data, + &session->userauth_pblc_data_len, 0, + NULL, 0, + &session-> + userauth_pblc_packet_requirev_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; LIBSSH2_FREE(session, session->userauth_pblc_method); @@ -764,7 +951,8 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use } if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Pubkey authentication prematurely successful"); + _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 @@ -788,7 +976,8 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use session->userauth_pblc_packet = NULL; LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; - libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED, "Username/PublicKey combination invalid", 0); + libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED, + "Username/PublicKey combination invalid", 0); session->userauth_pblc_state = libssh2_NB_state_idle; return -1; } @@ -797,8 +986,9 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use LIBSSH2_FREE(session, session->userauth_pblc_data); session->userauth_pblc_data = NULL; - if (libssh2_file_read_privatekey(session, &privkeyobj, &abstract, session->userauth_pblc_method, - session->userauth_pblc_method_len, privatekey, passphrase)) { + if (libssh2_file_read_privatekey + (session, &privkeyobj, &abstract, session->userauth_pblc_method, + session->userauth_pblc_method_len, privatekey, passphrase)) { LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; LIBSSH2_FREE(session, session->userauth_pblc_packet); @@ -836,10 +1026,11 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use if (sig_len > pubkeydata_len) { unsigned char *newpacket; /* Should *NEVER* happen, but...well.. better safe than sorry */ - newpacket = LIBSSH2_REALLOC(session, session->userauth_pblc_packet, session->userauth_pblc_packet_len + 4 + - (4 + session->userauth_pblc_method_len) + (4 + sig_len)); /* PK sigblob */ + newpacket = LIBSSH2_REALLOC(session, session->userauth_pblc_packet, session->userauth_pblc_packet_len + 4 + (4 + session->userauth_pblc_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_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating additional space for userauth-publickey packet", + 0); LIBSSH2_FREE(session, sig); LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; @@ -851,32 +1042,43 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use session->userauth_pblc_packet = newpacket; } - session->userauth_pblc_s = session->userauth_pblc_packet + session->userauth_pblc_packet_len; + session->userauth_pblc_s = + session->userauth_pblc_packet + session->userauth_pblc_packet_len; - libssh2_htonu32(session->userauth_pblc_s, 4 + session->userauth_pblc_method_len + 4 + sig_len); session->userauth_pblc_s += 4; + libssh2_htonu32(session->userauth_pblc_s, + 4 + session->userauth_pblc_method_len + 4 + sig_len); + session->userauth_pblc_s += 4; - libssh2_htonu32(session->userauth_pblc_s, session->userauth_pblc_method_len); session->userauth_pblc_s += 4; - memcpy(session->userauth_pblc_s, session->userauth_pblc_method, session->userauth_pblc_method_len); - session->userauth_pblc_s += session->userauth_pblc_method_len; + libssh2_htonu32(session->userauth_pblc_s, + session->userauth_pblc_method_len); + session->userauth_pblc_s += 4; + memcpy(session->userauth_pblc_s, session->userauth_pblc_method, + session->userauth_pblc_method_len); + session->userauth_pblc_s += session->userauth_pblc_method_len; LIBSSH2_FREE(session, session->userauth_pblc_method); session->userauth_pblc_method = NULL; - libssh2_htonu32(session->userauth_pblc_s, sig_len); session->userauth_pblc_s += 4; - memcpy(session->userauth_pblc_s, sig, sig_len); session->userauth_pblc_s += sig_len; + libssh2_htonu32(session->userauth_pblc_s, sig_len); + session->userauth_pblc_s += 4; + memcpy(session->userauth_pblc_s, sig, sig_len); + session->userauth_pblc_s += sig_len; LIBSSH2_FREE(session, sig); - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting publickey authentication -- phase 2"); - + _libssh2_debug(session, LIBSSH2_DBG_AUTH, + "Attempting publickey authentication -- phase 2"); + session->userauth_pblc_state = libssh2_NB_state_sent1; } - + if (session->userauth_pblc_state == libssh2_NB_state_sent1) { - rc = libssh2_packet_write(session, session->userauth_pblc_packet, session->userauth_pblc_s - session->userauth_pblc_packet); + rc = libssh2_packet_write(session, session->userauth_pblc_packet, + session->userauth_pblc_s - + session->userauth_pblc_packet); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-publickey request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-publickey request", 0); LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; session->userauth_pblc_state = libssh2_NB_state_idle; @@ -884,25 +1086,29 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use } LIBSSH2_FREE(session, session->userauth_pblc_packet); session->userauth_pblc_packet = NULL; - + session->userauth_pblc_state = libssh2_NB_state_sent2; } - + /* PK_OK is no longer valid */ reply_codes[2] = 0; - - rc = libssh2_packet_requirev_ex(session, reply_codes, &session->userauth_pblc_data, &session->userauth_pblc_data_len, 0, NULL, 0, - &session->userauth_pblc_packet_requirev_state); + + rc = libssh2_packet_requirev_ex(session, reply_codes, + &session->userauth_pblc_data, + &session->userauth_pblc_data_len, 0, NULL, + 0, + &session-> + userauth_pblc_packet_requirev_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { session->userauth_pblc_state = libssh2_NB_state_idle; return -1; } if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Publickey authentication successful"); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, + "Publickey authentication successful"); /* We are us and we've proved it. */ LIBSSH2_FREE(session, session->userauth_pblc_data); session->userauth_pblc_data = NULL; @@ -915,27 +1121,32 @@ libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, const char *use LIBSSH2_FREE(session, session->userauth_pblc_data); session->userauth_pblc_data = NULL; libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, - "Invalid signature for supplied public key, or bad username/public key combination", 0); + "Invalid signature for supplied public key, or bad username/public key combination", + 0); session->userauth_pblc_state = libssh2_NB_state_idle; return -1; } + /* }}} */ /* {{{ libssh2_userauth_keyboard_interactive * 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_keyboard_interactive_ex(LIBSSH2_SESSION * session, + const char *username, + unsigned int username_len, LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))) { unsigned char *s; int rc; - + static const unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, - SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0 }; + SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0 + }; unsigned int language_tag_len; unsigned int i; - + if (session->userauth_kybd_state == libssh2_NB_state_idle) { session->userauth_kybd_auth_name = NULL; session->userauth_kybd_auth_instruction = NULL; @@ -943,57 +1154,70 @@ libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *u session->userauth_kybd_auth_failure = 1; session->userauth_kybd_prompts = NULL; session->userauth_kybd_responses = NULL; - + /* Zero the whole thing out */ - memset(&session->userauth_kybd_packet_requirev_state, 0, sizeof(session->userauth_kybd_packet_requirev_state)); - - session->userauth_kybd_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) */ + memset(&session->userauth_kybd_packet_requirev_state, 0, + sizeof(session->userauth_kybd_packet_requirev_state)); + + session->userauth_kybd_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) */ ; - session->userauth_kybd_data = s = LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); + session->userauth_kybd_data = s = + LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); if (!s) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive authentication", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for keyboard-interactive authentication", + 0); return -1; } *s++ = SSH_MSG_USERAUTH_REQUEST; /* user name */ - libssh2_htonu32(s, username_len); s += 4; - memcpy(s, username, username_len); s += username_len; + 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; + 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; + 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; + libssh2_htonu32(s, 0); + s += 4; /* submethods */ - libssh2_htonu32(s, 0); s += 4; + libssh2_htonu32(s, 0); + s += 4; + + _libssh2_debug(session, LIBSSH2_DBG_AUTH, + "Attempting keyboard-interactive authentication"); - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Attempting keyboard-interactive authentication"); - session->userauth_kybd_state = libssh2_NB_state_created; } if (session->userauth_kybd_state == libssh2_NB_state_created) { - rc = libssh2_packet_write(session, session->userauth_kybd_data, session->userauth_kybd_packet_len); + rc = libssh2_packet_write(session, session->userauth_kybd_data, + session->userauth_kybd_packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send keyboard-interactive request", 0); + } else if (rc) { + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send keyboard-interactive request", 0); LIBSSH2_FREE(session, session->userauth_kybd_data); session->userauth_kybd_data = NULL; session->userauth_kybd_state = libssh2_NB_state_idle; @@ -1001,24 +1225,28 @@ libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *u } LIBSSH2_FREE(session, session->userauth_kybd_data); session->userauth_kybd_data = NULL; - + session->userauth_kybd_state = libssh2_NB_state_sent; } - for (;;) { + for(;;) { if (session->userauth_kybd_state == libssh2_NB_state_sent) { - rc = libssh2_packet_requirev_ex(session, reply_codes, &session->userauth_kybd_data, &session->userauth_kybd_data_len, - 0, NULL, 0, &session->userauth_kybd_packet_requirev_state); + rc = libssh2_packet_requirev_ex(session, reply_codes, + &session->userauth_kybd_data, + &session->userauth_kybd_data_len, + 0, NULL, 0, + &session-> + userauth_kybd_packet_requirev_state); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; - } - else if (rc) { + } else if (rc) { session->userauth_kybd_state = libssh2_NB_state_idle; return -1; } if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { - _libssh2_debug(session, LIBSSH2_DBG_AUTH, "Keyboard-interactive authentication successful"); + _libssh2_debug(session, LIBSSH2_DBG_AUTH, + "Keyboard-interactive authentication successful"); LIBSSH2_FREE(session, session->userauth_kybd_data); session->userauth_kybd_data = NULL; session->state |= LIBSSH2_STATE_AUTHENTICATED; @@ -1038,116 +1266,159 @@ libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *u s = session->userauth_kybd_data + 1; /* string name (ISO-10646 UTF-8) */ - session->userauth_kybd_auth_name_len = libssh2_ntohu32(s); s += 4; - session->userauth_kybd_auth_name = LIBSSH2_ALLOC(session, session->userauth_kybd_auth_name_len); + session->userauth_kybd_auth_name_len = libssh2_ntohu32(s); + s += 4; + session->userauth_kybd_auth_name = + LIBSSH2_ALLOC(session, session->userauth_kybd_auth_name_len); if (!session->userauth_kybd_auth_name) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate memory for keyboard-interactive 'name' request field", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for keyboard-interactive 'name' request field", + 0); goto cleanup; } - memcpy(session->userauth_kybd_auth_name, s, session->userauth_kybd_auth_name_len); s += session->userauth_kybd_auth_name_len; + memcpy(session->userauth_kybd_auth_name, s, + session->userauth_kybd_auth_name_len); + s += session->userauth_kybd_auth_name_len; /* string instruction (ISO-10646 UTF-8) */ - session->userauth_kybd_auth_instruction_len = libssh2_ntohu32(s); s += 4; - session->userauth_kybd_auth_instruction = LIBSSH2_ALLOC(session, session->userauth_kybd_auth_instruction_len); + session->userauth_kybd_auth_instruction_len = libssh2_ntohu32(s); + s += 4; + session->userauth_kybd_auth_instruction = + LIBSSH2_ALLOC(session, + session->userauth_kybd_auth_instruction_len); if (!session->userauth_kybd_auth_instruction) { libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate memory for keyboard-interactive 'instruction' request field", 0); + "Unable to allocate memory for keyboard-interactive 'instruction' request field", + 0); goto cleanup; } - memcpy(session->userauth_kybd_auth_instruction, s, session->userauth_kybd_auth_instruction_len); - s += session->userauth_kybd_auth_instruction_len; + memcpy(session->userauth_kybd_auth_instruction, s, + session->userauth_kybd_auth_instruction_len); + s += session->userauth_kybd_auth_instruction_len; /* string language tag (as defined in [RFC-3066]) */ - language_tag_len = libssh2_ntohu32(s); s += 4; + language_tag_len = libssh2_ntohu32(s); + s += 4; /* ignoring this field as deprecated */ - s += language_tag_len; + s += language_tag_len; /* int num-prompts */ - session->userauth_kybd_num_prompts = libssh2_ntohu32(s); s += 4; + session->userauth_kybd_num_prompts = libssh2_ntohu32(s); + s += 4; session->userauth_kybd_prompts = - LIBSSH2_ALLOC(session, sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * session->userauth_kybd_num_prompts); + LIBSSH2_ALLOC(session, + sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * + session->userauth_kybd_num_prompts); if (!session->userauth_kybd_prompts) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for keyboard-interactive prompts array", 0); + libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for keyboard-interactive prompts array", + 0); goto cleanup; } - memset(session->userauth_kybd_prompts, 0, sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * session->userauth_kybd_num_prompts); + memset(session->userauth_kybd_prompts, 0, + sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * + session->userauth_kybd_num_prompts); session->userauth_kybd_responses = - LIBSSH2_ALLOC(session, sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * session->userauth_kybd_num_prompts); + LIBSSH2_ALLOC(session, + sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * + session->userauth_kybd_num_prompts); if (!session->userauth_kybd_responses) { libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate memory for keyboard-interactive responses array", 0); + "Unable to allocate memory for keyboard-interactive responses array", + 0); goto cleanup; } - memset(session->userauth_kybd_responses, 0, sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * session->userauth_kybd_num_prompts); + memset(session->userauth_kybd_responses, 0, + sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * + session->userauth_kybd_num_prompts); for(i = 0; i != session->userauth_kybd_num_prompts; ++i) { /* string prompt[1] (ISO-10646 UTF-8) */ - session->userauth_kybd_prompts[i].length = libssh2_ntohu32(s); s += 4; - session->userauth_kybd_prompts[i].text = LIBSSH2_ALLOC(session, session->userauth_kybd_prompts[i].length); + session->userauth_kybd_prompts[i].length = libssh2_ntohu32(s); + s += 4; + session->userauth_kybd_prompts[i].text = + LIBSSH2_ALLOC(session, + session->userauth_kybd_prompts[i].length); if (!session->userauth_kybd_prompts[i].text) { libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate memory for keyboard-interactive prompt message", 0); + "Unable to allocate memory for keyboard-interactive prompt message", + 0); goto cleanup; } - memcpy(session->userauth_kybd_prompts[i].text, s, session->userauth_kybd_prompts[i].length); + memcpy(session->userauth_kybd_prompts[i].text, s, + session->userauth_kybd_prompts[i].length); s += session->userauth_kybd_prompts[i].length; /* boolean echo[1] */ session->userauth_kybd_prompts[i].echo = *s++; } - response_callback(session->userauth_kybd_auth_name, session->userauth_kybd_auth_name_len, session->userauth_kybd_auth_instruction, - session->userauth_kybd_auth_instruction_len, session->userauth_kybd_num_prompts, session->userauth_kybd_prompts, - session->userauth_kybd_responses, &session->abstract); + response_callback(session->userauth_kybd_auth_name, + session->userauth_kybd_auth_name_len, + session->userauth_kybd_auth_instruction, + session->userauth_kybd_auth_instruction_len, + session->userauth_kybd_num_prompts, + session->userauth_kybd_prompts, + session->userauth_kybd_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"); - session->userauth_kybd_packet_len = - 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */ - + 4 /* int num-responses */ + session->userauth_kybd_packet_len = 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */ + + 4 /* int num-responses */ ; - for (i = 0; i != session->userauth_kybd_num_prompts; ++i) { + for(i = 0; i != session->userauth_kybd_num_prompts; ++i) { /* string response[1] (ISO-10646 UTF-8) */ - session->userauth_kybd_packet_len += 4 + session->userauth_kybd_responses[i].length; + session->userauth_kybd_packet_len += + 4 + session->userauth_kybd_responses[i].length; } - session->userauth_kybd_data = s = LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); + session->userauth_kybd_data = s = + LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); if (!s) { - libssh2_error(session, LIBSSH2_ERROR_ALLOC, - "Unable to allocate memory for keyboard-interactive response packet", 0); + 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, session->userauth_kybd_num_prompts); s += 4; + *s = SSH_MSG_USERAUTH_INFO_RESPONSE; + s++; + libssh2_htonu32(s, session->userauth_kybd_num_prompts); + s += 4; - for (i = 0; i != session->userauth_kybd_num_prompts; ++i) { - libssh2_htonu32(s, session->userauth_kybd_responses[i].length); s += 4; - memcpy(s, session->userauth_kybd_responses[i].text, session->userauth_kybd_responses[i].length); - s += session->userauth_kybd_responses[i].length; + for(i = 0; i != session->userauth_kybd_num_prompts; ++i) { + libssh2_htonu32(s, session->userauth_kybd_responses[i].length); + s += 4; + memcpy(s, session->userauth_kybd_responses[i].text, + session->userauth_kybd_responses[i].length); + s += session->userauth_kybd_responses[i].length; } - + session->userauth_kybd_state = libssh2_NB_state_sent1; } if (session->userauth_kybd_state == libssh2_NB_state_sent1) { - rc = libssh2_packet_write(session, session->userauth_kybd_data, session->userauth_kybd_packet_len); + rc = libssh2_packet_write(session, session->userauth_kybd_data, + session->userauth_kybd_packet_len); if (rc == PACKET_EAGAIN) { return PACKET_EAGAIN; } if (rc) { - libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-keyboard-interactive request", 0); + libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-keyboard-interactive request", + 0); goto cleanup; } session->userauth_kybd_auth_failure = 0; } - cleanup: + cleanup: /* * It's safe to clean all the data here, because unallocated pointers * are filled by zeroes @@ -1157,15 +1428,16 @@ libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *u session->userauth_kybd_data = NULL; if (session->userauth_kybd_prompts) { - for (i = 0; i != session->userauth_kybd_num_prompts; ++i) { + for(i = 0; i != session->userauth_kybd_num_prompts; ++i) { LIBSSH2_FREE(session, session->userauth_kybd_prompts[i].text); session->userauth_kybd_prompts[i].text = NULL; } } if (session->userauth_kybd_responses) { - for (i = 0; i != session->userauth_kybd_num_prompts; ++i) { - LIBSSH2_FREE(session, session->userauth_kybd_responses[i].text); + for(i = 0; i != session->userauth_kybd_num_prompts; ++i) { + LIBSSH2_FREE(session, + session->userauth_kybd_responses[i].text); session->userauth_kybd_responses[i].text = NULL; } } @@ -1179,8 +1451,9 @@ libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, const char *u session->userauth_kybd_state = libssh2_NB_state_idle; return -1; } - + session->userauth_kybd_state = libssh2_NB_state_sent; } } + /* }}} */