_libssh2_transport_send: replaces _libssh2_transport_write
The new function takes two data areas, combines them and sends them as a single SSH packet. This allows several functions to allocate and copy less data. I also found and fixed a mixed up use of the compression function arguments that I introduced in my rewrite in a recent commit.
Этот коммит содержится в:
родитель
d9cdd8c0a7
Коммит
c48840ba88
148
src/channel.c
148
src/channel.c
@ -130,7 +130,8 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
uint32_t channel_type_len,
|
||||
uint32_t window_size,
|
||||
uint32_t packet_size,
|
||||
const char *message, unsigned int message_len)
|
||||
const unsigned char *message,
|
||||
size_t message_len)
|
||||
{
|
||||
static const unsigned char reply_codes[3] = {
|
||||
SSH_MSG_CHANNEL_OPEN_CONFIRMATION,
|
||||
@ -146,7 +147,7 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
session->open_data = NULL;
|
||||
/* 17 = packet_type(1) + channel_type_len(4) + sender_channel(4) +
|
||||
* window_size(4) + packet_size(4) */
|
||||
session->open_packet_len = channel_type_len + message_len + 17;
|
||||
session->open_packet_len = channel_type_len + 17;
|
||||
session->open_local_channel = _libssh2_channel_nextid(session);
|
||||
|
||||
/* Zero the whole thing out */
|
||||
@ -201,17 +202,16 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
_libssh2_store_u32(&s, window_size);
|
||||
_libssh2_store_u32(&s, packet_size);
|
||||
|
||||
if (message && message_len) {
|
||||
memcpy(s, message, message_len);
|
||||
s += message_len;
|
||||
}
|
||||
/* Do not copy the message */
|
||||
|
||||
session->open_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
if (session->open_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, session->open_packet,
|
||||
session->open_packet_len);
|
||||
rc = _libssh2_transport_send(session,
|
||||
session->open_packet,
|
||||
session->open_packet_len,
|
||||
message, message_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending channel-open request");
|
||||
@ -304,12 +304,6 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
session->open_data = NULL;
|
||||
}
|
||||
|
||||
/* Free any state variables still holding data */
|
||||
if (session->open_channel->write_packet) {
|
||||
LIBSSH2_FREE(session, session->open_channel->write_packet);
|
||||
session->open_channel->write_packet = NULL;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, session->open_channel);
|
||||
session->open_channel = NULL;
|
||||
}
|
||||
@ -337,7 +331,8 @@ libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *type,
|
||||
BLOCK_ADJUST_ERRNO(ptr, session,
|
||||
_libssh2_channel_open(session, type, type_len,
|
||||
window_size, packet_size,
|
||||
msg, msg_len));
|
||||
(unsigned char *)msg,
|
||||
msg_len));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -382,7 +377,7 @@ channel_direct_tcpip(LIBSSH2_SESSION * session, const char *host,
|
||||
sizeof("direct-tcpip") - 1,
|
||||
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
|
||||
LIBSSH2_CHANNEL_PACKET_DEFAULT,
|
||||
(char *) session->direct_message,
|
||||
session->direct_message,
|
||||
session->direct_message_len);
|
||||
|
||||
if (!channel &&
|
||||
@ -434,9 +429,11 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
|
||||
{ SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 };
|
||||
int rc;
|
||||
|
||||
if(!host)
|
||||
host = "0.0.0.0";
|
||||
|
||||
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 = strlen(host);
|
||||
/* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4)
|
||||
+ port(4) */
|
||||
session->fwdLstn_packet_len =
|
||||
@ -462,16 +459,17 @@ channel_forward_listen(LIBSSH2_SESSION * session, const char *host,
|
||||
_libssh2_store_str(&s, "tcpip-forward", sizeof("tcpip-forward") - 1);
|
||||
*(s++) = 0x01; /* want_reply */
|
||||
|
||||
_libssh2_store_str(&s, host ? host : "0.0.0.0",
|
||||
session->fwdLstn_host_len);
|
||||
_libssh2_store_str(&s, host, session->fwdLstn_host_len);
|
||||
_libssh2_store_u32(&s, port);
|
||||
|
||||
session->fwdLstn_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
if (session->fwdLstn_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, session->fwdLstn_packet,
|
||||
session->fwdLstn_packet_len);
|
||||
rc = _libssh2_transport_send(session,
|
||||
session->fwdLstn_packet,
|
||||
session->fwdLstn_packet_len,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending global-request packet for "
|
||||
@ -635,7 +633,7 @@ int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener)
|
||||
}
|
||||
|
||||
if (listener->chanFwdCncl_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, packet, packet_len);
|
||||
rc = _libssh2_transport_send(session, packet, packet_len, NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending forward request");
|
||||
@ -804,8 +802,10 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
|
||||
}
|
||||
|
||||
if (channel->setenv_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, channel->setenv_packet,
|
||||
channel->setenv_packet_len);
|
||||
rc = _libssh2_transport_send(session,
|
||||
channel->setenv_packet,
|
||||
channel->setenv_packet_len,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending setenv request");
|
||||
@ -894,6 +894,11 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
|
||||
/* 41 = packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) +
|
||||
* want_reply(1) + term_len(4) + width(4) + height(4) + width_px(4) +
|
||||
* height_px(4) + modes_len(4) */
|
||||
if(term_len + modes_len > 256) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"term + mode lengths too large");
|
||||
}
|
||||
|
||||
channel->reqPTY_packet_len = term_len + modes_len + 41;
|
||||
|
||||
/* Zero the whole thing out */
|
||||
@ -904,12 +909,7 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
|
||||
"Allocating tty on channel %lu/%lu", channel->local.id,
|
||||
channel->remote.id);
|
||||
|
||||
s = channel->reqPTY_packet =
|
||||
LIBSSH2_ALLOC(session, channel->reqPTY_packet_len);
|
||||
if (!channel->reqPTY_packet) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for pty-request");
|
||||
}
|
||||
s = channel->reqPTY_packet;
|
||||
|
||||
*(s++) = SSH_MSG_CHANNEL_REQUEST;
|
||||
_libssh2_store_u32(&s, channel->remote.id);
|
||||
@ -928,22 +928,18 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
|
||||
}
|
||||
|
||||
if (channel->reqPTY_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, channel->reqPTY_packet,
|
||||
channel->reqPTY_packet_len);
|
||||
rc = _libssh2_transport_send(session, channel->reqPTY_packet,
|
||||
channel->reqPTY_packet_len,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending pty request");
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||
channel->reqPTY_packet = NULL;
|
||||
channel->reqPTY_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, rc,
|
||||
"Unable to send pty-request packet");
|
||||
}
|
||||
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||
channel->reqPTY_packet = NULL;
|
||||
|
||||
_libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id);
|
||||
|
||||
channel->reqPTY_state = libssh2_NB_state_sent;
|
||||
@ -1019,12 +1015,7 @@ channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width,
|
||||
channel->local.id,
|
||||
channel->remote.id);
|
||||
|
||||
s = channel->reqPTY_packet =
|
||||
LIBSSH2_ALLOC(session, channel->reqPTY_packet_len);
|
||||
|
||||
if (!channel->reqPTY_packet)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for pty-request");
|
||||
s = channel->reqPTY_packet;
|
||||
|
||||
*(s++) = SSH_MSG_CHANNEL_REQUEST;
|
||||
_libssh2_store_u32(&s, channel->remote.id);
|
||||
@ -1040,21 +1031,18 @@ channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width,
|
||||
}
|
||||
|
||||
if (channel->reqPTY_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, channel->reqPTY_packet,
|
||||
channel->reqPTY_packet_len);
|
||||
rc = _libssh2_transport_send(session, channel->reqPTY_packet,
|
||||
channel->reqPTY_packet_len,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending window-change request");
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||
channel->reqPTY_packet = NULL;
|
||||
channel->reqPTY_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, rc,
|
||||
"Unable to send window-change packet");
|
||||
}
|
||||
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||
channel->reqPTY_packet = NULL;
|
||||
_libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id);
|
||||
channel->reqPTY_state = libssh2_NB_state_sent;
|
||||
|
||||
@ -1162,8 +1150,9 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
|
||||
}
|
||||
|
||||
if (channel->reqX11_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, channel->reqX11_packet,
|
||||
channel->reqX11_packet_len);
|
||||
rc = _libssh2_transport_send(session, channel->reqX11_packet,
|
||||
channel->reqX11_packet_len,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending X11-req packet");
|
||||
@ -1258,7 +1247,7 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
|
||||
sizeof(channel->process_packet_requirev_state));
|
||||
|
||||
if (message)
|
||||
channel->process_packet_len += message_len + 4;
|
||||
channel->process_packet_len += + 4;
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
"starting request(%s) on channel %lu/%lu, message=%s",
|
||||
@ -1277,14 +1266,16 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
|
||||
*(s++) = 0x01;
|
||||
|
||||
if (message)
|
||||
_libssh2_store_str(&s, message, message_len);
|
||||
_libssh2_store_u32(&s, message_len);
|
||||
|
||||
channel->process_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
if (channel->process_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, channel->process_packet,
|
||||
channel->process_packet_len);
|
||||
rc = _libssh2_transport_send(session,
|
||||
channel->process_packet,
|
||||
channel->process_packet_len,
|
||||
(unsigned char *)message, message_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending channel request");
|
||||
@ -1588,7 +1579,8 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
||||
channel->adjust_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
rc = _libssh2_transport_write(channel->session, channel->adjust_adjust, 9);
|
||||
rc = _libssh2_transport_send(channel->session, channel->adjust_adjust, 9,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(channel->session, rc,
|
||||
"Would block sending window adjust");
|
||||
@ -1987,7 +1979,7 @@ _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id)
|
||||
*/
|
||||
ssize_t
|
||||
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
const char *buf, size_t buflen)
|
||||
const unsigned char *buf, size_t buflen)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
int rc;
|
||||
@ -2022,15 +2014,7 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
|
||||
/* [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);
|
||||
if (!channel->write_packet) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocte space "
|
||||
"for data transmission packet");
|
||||
}
|
||||
|
||||
channel->write_packet_len = (stream_id ? 13 : 9);
|
||||
channel->write_state = libssh2_NB_state_allocated;
|
||||
}
|
||||
|
||||
@ -2079,7 +2063,9 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
channel->remote.id, stream_id);
|
||||
channel->write_bufwrite = channel->local.packet_size;
|
||||
}
|
||||
_libssh2_store_str(&channel->write_s, buf, channel->write_bufwrite);
|
||||
/* store the size here only, the buffer is passed in as-is to
|
||||
_libssh2_transport_send() */
|
||||
_libssh2_store_u32(&channel->write_s, channel->write_bufwrite);
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
||||
"Sending %d bytes on channel %lu/%lu, stream_id=%d",
|
||||
@ -2090,16 +2076,15 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
}
|
||||
|
||||
if (channel->write_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, channel->write_packet,
|
||||
channel->write_s -
|
||||
channel->write_packet);
|
||||
rc = _libssh2_transport_send(session, channel->write_packet,
|
||||
channel->write_s -
|
||||
channel->write_packet,
|
||||
buf, channel->write_bufwrite);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return _libssh2_error(session, rc,
|
||||
"Unable to send channel data");
|
||||
}
|
||||
else if (rc) {
|
||||
LIBSSH2_FREE(session, channel->write_packet);
|
||||
channel->write_packet = NULL;
|
||||
channel->write_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, rc,
|
||||
"Unable to send channel data");
|
||||
@ -2122,9 +2107,6 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
}
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, channel->write_packet);
|
||||
channel->write_packet = NULL;
|
||||
|
||||
channel->write_state = libssh2_NB_state_idle;
|
||||
|
||||
return wrote;
|
||||
@ -2145,7 +2127,8 @@ libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
|
||||
BLOCK_ADJUST(rc, channel->session,
|
||||
_libssh2_channel_write(channel, stream_id, buf, buflen));
|
||||
_libssh2_channel_write(channel, stream_id,
|
||||
(unsigned char *)buf, buflen));
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -2164,7 +2147,7 @@ static int channel_send_eof(LIBSSH2_CHANNEL *channel)
|
||||
channel->local.id, channel->remote.id);
|
||||
packet[0] = SSH_MSG_CHANNEL_EOF;
|
||||
_libssh2_htonu32(packet + 1, channel->remote.id);
|
||||
rc = _libssh2_transport_write(session, packet, 5);
|
||||
rc = _libssh2_transport_send(session, packet, 5, NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending EOF");
|
||||
@ -2316,7 +2299,8 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
|
||||
}
|
||||
|
||||
if (channel->close_state == libssh2_NB_state_created) {
|
||||
retcode = _libssh2_transport_write(session, channel->close_packet, 5);
|
||||
retcode = _libssh2_transport_send(session, channel->close_packet, 5,
|
||||
NULL, 0);
|
||||
if (retcode == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, rc,
|
||||
"Would block sending close-channel");
|
||||
@ -2508,18 +2492,12 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
|
||||
if (channel->setenv_packet) {
|
||||
LIBSSH2_FREE(session, channel->setenv_packet);
|
||||
}
|
||||
if (channel->reqPTY_packet) {
|
||||
LIBSSH2_FREE(session, channel->reqPTY_packet);
|
||||
}
|
||||
if (channel->reqX11_packet) {
|
||||
LIBSSH2_FREE(session, channel->reqX11_packet);
|
||||
}
|
||||
if (channel->process_packet) {
|
||||
LIBSSH2_FREE(session, channel->process_packet);
|
||||
}
|
||||
if (channel->write_packet) {
|
||||
LIBSSH2_FREE(session, channel->write_packet);
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, channel);
|
||||
|
||||
|
@ -80,7 +80,7 @@ _libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
|
||||
*/
|
||||
ssize_t
|
||||
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
const char *buf, size_t buflen);
|
||||
const unsigned char *buf, size_t buflen);
|
||||
|
||||
/*
|
||||
* _libssh2_channel_open
|
||||
@ -92,7 +92,7 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
uint32_t channel_type_len,
|
||||
uint32_t window_size,
|
||||
uint32_t packet_size,
|
||||
const char *message, unsigned int message_len);
|
||||
const unsigned char *message, unsigned int message_len);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -68,7 +68,8 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
|
||||
now = time (NULL);
|
||||
|
||||
if (session->keepalive_last_sent + session->keepalive_interval <= now) {
|
||||
/* Format is "SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */
|
||||
/* Format is
|
||||
"SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */
|
||||
unsigned char keepalive_data[]
|
||||
= "\x50\x00\x00\x00\x15keepalive@libssh2.orgW";
|
||||
size_t len = sizeof (keepalive_data) - 1;
|
||||
@ -76,9 +77,9 @@ libssh2_keepalive_send (LIBSSH2_SESSION *session,
|
||||
|
||||
keepalive_data[len - 1] = session->keepalive_want_reply;
|
||||
|
||||
rc = _libssh2_transport_write(session, keepalive_data, len);
|
||||
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
|
||||
already full, sending another keepalive is not useful. */
|
||||
rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0);
|
||||
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
|
||||
already full, sending another keepalive is not useful. */
|
||||
if (rc && rc != LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send keepalive message");
|
||||
|
13
src/kex.c
13
src/kex.c
@ -141,8 +141,9 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
if (exchange_state->state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, exchange_state->e_packet,
|
||||
exchange_state->e_packet_len);
|
||||
rc = _libssh2_transport_send(session, exchange_state->e_packet,
|
||||
exchange_state->e_packet_len,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
@ -411,7 +412,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
if (exchange_state->state == libssh2_NB_state_sent2) {
|
||||
rc = _libssh2_transport_write(session, &exchange_state->c, 1);
|
||||
rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
@ -844,8 +845,8 @@ kex_method_diffie_hellman_group_exchange_sha1_key_exchange
|
||||
}
|
||||
|
||||
if (key_state->state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, key_state->request,
|
||||
key_state->request_len);
|
||||
rc = _libssh2_transport_send(session, key_state->request,
|
||||
key_state->request_len, NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
@ -1139,7 +1140,7 @@ static int kexinit(LIBSSH2_SESSION * session)
|
||||
session->kexinit_data_len = 0;
|
||||
}
|
||||
|
||||
rc = _libssh2_transport_write(session, data, data_len);
|
||||
rc = _libssh2_transport_send(session, data, data_len, NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
session->kexinit_data = data;
|
||||
session->kexinit_data_len = data_len;
|
||||
|
@ -359,9 +359,10 @@ struct _LIBSSH2_CHANNEL
|
||||
unsigned char setenv_local_channel[4];
|
||||
packet_requirev_state_t setenv_packet_requirev_state;
|
||||
|
||||
/* State variables used in libssh2_channel_request_pty_ex() */
|
||||
/* State variables used in libssh2_channel_request_pty_ex()
|
||||
libssh2_channel_request_pty_size_ex() */
|
||||
libssh2_nonblocking_states reqPTY_state;
|
||||
unsigned char *reqPTY_packet;
|
||||
unsigned char reqPTY_packet[41 + 256];
|
||||
size_t reqPTY_packet_len;
|
||||
unsigned char reqPTY_local_channel[4];
|
||||
packet_requirev_state_t reqPTY_packet_requirev_state;
|
||||
@ -396,7 +397,7 @@ struct _LIBSSH2_CHANNEL
|
||||
|
||||
/* State variables used in libssh2_channel_write_ex() */
|
||||
libssh2_nonblocking_states write_state;
|
||||
unsigned char *write_packet;
|
||||
unsigned char write_packet[13];
|
||||
unsigned char *write_s;
|
||||
size_t write_packet_len;
|
||||
size_t write_bufwrote;
|
||||
@ -495,8 +496,7 @@ struct transportpacket
|
||||
unsigned char outbuf[MAX_SSH_PACKET_LEN]; /* 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 */
|
||||
const unsigned char *odata; /* original pointer to the data */
|
||||
size_t olen; /* original size of the data we stored in
|
||||
outbuf */
|
||||
size_t osent; /* number of bytes already sent */
|
||||
@ -774,7 +774,7 @@ struct _LIBSSH2_SESSION
|
||||
|
||||
/* State variables used in libssh2_session_disconnect_ex() */
|
||||
libssh2_nonblocking_states disconnect_state;
|
||||
unsigned char *disconnect_data;
|
||||
unsigned char disconnect_data[256 + 13];
|
||||
size_t disconnect_data_len;
|
||||
|
||||
/* State variables used in libssh2_packet_read() */
|
||||
|
20
src/packet.c
20
src/packet.c
@ -1,6 +1,6 @@
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2005,2006 Mikhail Gusarov
|
||||
* Copyright (c) 2009 by Daniel Stenberg
|
||||
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -204,8 +204,8 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
}
|
||||
|
||||
if (listen_state->state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, listen_state->packet,
|
||||
17);
|
||||
rc = _libssh2_transport_send(session, listen_state->packet,
|
||||
17, NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return rc;
|
||||
else if (rc) {
|
||||
@ -239,8 +239,8 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
_libssh2_store_str(&p, FwdNotReq, sizeof(FwdNotReq) - 1);
|
||||
_libssh2_htonu32(p, 0);
|
||||
|
||||
rc = _libssh2_transport_write(session, listen_state->packet,
|
||||
packet_len);
|
||||
rc = _libssh2_transport_send(session, listen_state->packet,
|
||||
packet_len, NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
@ -349,7 +349,8 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
}
|
||||
|
||||
if (x11open_state->state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, x11open_state->packet, 17);
|
||||
rc = _libssh2_transport_send(session, x11open_state->packet, 17,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
@ -384,7 +385,8 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
_libssh2_store_str(&p, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1);
|
||||
_libssh2_htonu32(p, 0);
|
||||
|
||||
rc = _libssh2_transport_write(session, x11open_state->packet, packet_len);
|
||||
rc = _libssh2_transport_send(session, x11open_state->packet, packet_len,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if (rc) {
|
||||
@ -589,7 +591,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
libssh2_packet_add_jump_point5:
|
||||
session->packAdd_state = libssh2_NB_state_jump5;
|
||||
data[0] = SSH_MSG_REQUEST_FAILURE;
|
||||
rc = _libssh2_transport_write(session, data, 1);
|
||||
rc = _libssh2_transport_send(session, data, 1, NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return rc;
|
||||
LIBSSH2_FREE(session, data);
|
||||
@ -800,7 +802,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
libssh2_packet_add_jump_point4:
|
||||
session->packAdd_state = libssh2_NB_state_jump4;
|
||||
data[0] = SSH_MSG_CHANNEL_FAILURE;
|
||||
rc = _libssh2_transport_write(session, data, 5);
|
||||
rc = _libssh2_transport_send(session, data, 5, NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return rc;
|
||||
LIBSSH2_FREE(session, data);
|
||||
|
@ -378,7 +378,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
|
||||
|
||||
if (session->pkeyInit_state == libssh2_NB_state_sent2) {
|
||||
rc = _libssh2_channel_write(session->pkeyInit_channel, 0,
|
||||
(char *)session->pkeyInit_buffer,
|
||||
session->pkeyInit_buffer,
|
||||
19 - session->pkeyInit_buffer_sent);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
@ -644,7 +644,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
|
||||
}
|
||||
|
||||
if (pkey->add_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) pkey->add_packet,
|
||||
rc = _libssh2_channel_write(channel, 0, pkey->add_packet,
|
||||
(pkey->add_s - pkey->add_packet));
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
@ -727,7 +727,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
|
||||
}
|
||||
|
||||
if (pkey->remove_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) pkey->remove_packet,
|
||||
rc = _libssh2_channel_write(channel, 0, pkey->remove_packet,
|
||||
(pkey->remove_s - pkey->remove_packet));
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
@ -794,7 +794,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
|
||||
|
||||
if (pkey->listFetch_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0,
|
||||
(char *) pkey->listFetch_buffer,
|
||||
pkey->listFetch_buffer,
|
||||
(pkey->listFetch_s -
|
||||
pkey->listFetch_buffer));
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
|
12
src/scp.c
12
src/scp.c
@ -360,7 +360,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent1) {
|
||||
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
|
||||
(char *) session->scpRecv_response, 1);
|
||||
session->scpRecv_response, 1);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending initial wakeup");
|
||||
@ -550,8 +550,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent3) {
|
||||
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
|
||||
(char *) session->
|
||||
scpRecv_response, 1);
|
||||
session->scpRecv_response, 1);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting to send SCP ACK");
|
||||
@ -708,8 +707,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, struct stat * sb)
|
||||
|
||||
if (session->scpRecv_state == libssh2_NB_state_sent6) {
|
||||
rc = _libssh2_channel_write(session->scpRecv_channel, 0,
|
||||
(char *) session->
|
||||
scpRecv_response, 1);
|
||||
session->scpRecv_response, 1);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block sending SCP ACK");
|
||||
@ -904,7 +902,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
|
||||
if (mtime || atime) {
|
||||
if (session->scpSend_state == libssh2_NB_state_sent2) {
|
||||
rc = _libssh2_channel_write(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response,
|
||||
session->scpSend_response,
|
||||
session->scpSend_response_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
@ -970,7 +968,7 @@ scp_send(LIBSSH2_SESSION * session, const char *path, int mode,
|
||||
|
||||
if (session->scpSend_state == libssh2_NB_state_sent5) {
|
||||
rc = _libssh2_channel_write(session->scpSend_channel, 0,
|
||||
(char *) session->scpSend_response,
|
||||
session->scpSend_response,
|
||||
session->scpSend_response_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
|
@ -683,8 +683,9 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
|
||||
}
|
||||
|
||||
if (session->startup_state == libssh2_NB_state_sent3) {
|
||||
rc = _libssh2_transport_write(session, session->startup_service,
|
||||
sizeof("ssh-userauth") + 5 - 1);
|
||||
rc = _libssh2_transport_send(session, session->startup_service,
|
||||
sizeof("ssh-userauth") + 5 - 1,
|
||||
NULL, 0);
|
||||
if (rc) {
|
||||
return _libssh2_error(session, rc,
|
||||
"Unable to ask for ssh-userauth service");
|
||||
@ -772,7 +773,6 @@ session_free(LIBSSH2_SESSION *session)
|
||||
LIBSSH2_PACKET *pkg;
|
||||
LIBSSH2_CHANNEL *ch;
|
||||
LIBSSH2_LISTENER *l;
|
||||
struct transportpacket *p = &session->packet;
|
||||
|
||||
if (session->free_state == libssh2_NB_state_idle) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Freeing session resource",
|
||||
@ -903,9 +903,6 @@ session_free(LIBSSH2_SESSION *session)
|
||||
if (session->startup_data) {
|
||||
LIBSSH2_FREE(session, session->startup_data);
|
||||
}
|
||||
if (session->disconnect_data) {
|
||||
LIBSSH2_FREE(session, session->disconnect_data);
|
||||
}
|
||||
if (session->userauth_list_data) {
|
||||
LIBSSH2_FREE(session, session->userauth_list_data);
|
||||
}
|
||||
@ -1014,7 +1011,8 @@ libssh2_session_free(LIBSSH2_SESSION * session)
|
||||
*/
|
||||
static int
|
||||
session_disconnect(LIBSSH2_SESSION *session, int reason,
|
||||
const char *description, const char *lang)
|
||||
const char *description,
|
||||
const char *lang)
|
||||
{
|
||||
unsigned char *s;
|
||||
unsigned long descr_len = 0, lang_len = 0;
|
||||
@ -1024,40 +1022,36 @@ session_disconnect(LIBSSH2_SESSION *session, int reason,
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"Disconnecting: reason=%d, desc=%s, lang=%s", reason,
|
||||
description, lang);
|
||||
if (description) {
|
||||
if (description)
|
||||
descr_len = strlen(description);
|
||||
}
|
||||
if (lang) {
|
||||
|
||||
if (lang)
|
||||
lang_len = strlen(lang);
|
||||
}
|
||||
|
||||
if(descr_len > 256)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
|
||||
"too long description");
|
||||
|
||||
/* 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);
|
||||
if (!session->disconnect_data) {
|
||||
session->disconnect_state = libssh2_NB_state_idle;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"disconnect packet");
|
||||
}
|
||||
s = session->disconnect_data;
|
||||
|
||||
*(s++) = SSH_MSG_DISCONNECT;
|
||||
_libssh2_store_u32(&s, reason);
|
||||
_libssh2_store_str(&s, description, descr_len);
|
||||
_libssh2_store_str(&s, lang, lang_len);
|
||||
/* store length only, lang is sent separately */
|
||||
_libssh2_store_u32(&s, lang_len);
|
||||
|
||||
session->disconnect_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
rc = _libssh2_transport_write(session, session->disconnect_data,
|
||||
session->disconnect_data_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
rc = _libssh2_transport_send(session, session->disconnect_data,
|
||||
session->disconnect_data_len,
|
||||
(unsigned char *)lang, lang_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return rc;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, session->disconnect_data);
|
||||
session->disconnect_data = NULL;
|
||||
session->disconnect_state = libssh2_NB_state_idle;
|
||||
|
||||
return 0;
|
||||
|
33
src/sftp.c
33
src/sftp.c
@ -611,7 +611,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
|
||||
if (session->sftpInit_state == libssh2_NB_state_sent2) {
|
||||
/* sent off what's left of the init buffer to send */
|
||||
rc = _libssh2_channel_write(session->sftpInit_channel, 0,
|
||||
(char *)session->sftpInit_buffer +
|
||||
session->sftpInit_buffer +
|
||||
session->sftpInit_sent,
|
||||
9 - session->sftpInit_sent);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
@ -877,7 +877,7 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
|
||||
}
|
||||
|
||||
if (sftp->open_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) sftp->open_packet+
|
||||
rc = _libssh2_channel_write(channel, 0, sftp->open_packet+
|
||||
sftp->open_packet_sent,
|
||||
sftp->open_packet_len -
|
||||
sftp->open_packet_sent);
|
||||
@ -1108,8 +1108,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
|
||||
}
|
||||
|
||||
if (sftp->read_state == libssh2_NB_state_created) {
|
||||
retcode = _libssh2_channel_write(channel, 0, (char *) packet,
|
||||
packet_len);
|
||||
retcode = _libssh2_channel_write(channel, 0, packet, packet_len);
|
||||
if (retcode == LIBSSH2_ERROR_EAGAIN) {
|
||||
sftp->read_packet = packet;
|
||||
sftp->read_request_id = request_id;
|
||||
@ -1300,8 +1299,7 @@ static int sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
|
||||
if (sftp->readdir_state == libssh2_NB_state_created) {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||
"Reading entries from directory handle");
|
||||
retcode = _libssh2_channel_write(channel, 0,
|
||||
(char *) sftp->readdir_packet,
|
||||
retcode = _libssh2_channel_write(channel, 0, sftp->readdir_packet,
|
||||
packet_len);
|
||||
if (retcode == LIBSSH2_ERROR_EAGAIN) {
|
||||
return retcode;
|
||||
@ -1429,7 +1427,7 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
|
||||
}
|
||||
|
||||
if (sftp->write_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *)sftp->write_packet,
|
||||
rc = _libssh2_channel_write(channel, 0, sftp->write_packet,
|
||||
packet_len);
|
||||
if(rc < 0) {
|
||||
/* error */
|
||||
@ -1533,7 +1531,7 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
|
||||
}
|
||||
|
||||
if (sftp->fstat_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) sftp->fstat_packet,
|
||||
rc = _libssh2_channel_write(channel, 0, sftp->fstat_packet,
|
||||
packet_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
@ -1682,7 +1680,7 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
|
||||
}
|
||||
|
||||
if (handle->close_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) handle->close_packet,
|
||||
rc = _libssh2_channel_write(channel, 0, handle->close_packet,
|
||||
packet_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
@ -1793,7 +1791,7 @@ static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename,
|
||||
}
|
||||
|
||||
if (sftp->unlink_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) sftp->unlink_packet,
|
||||
rc = _libssh2_channel_write(channel, 0, sftp->unlink_packet,
|
||||
packet_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
@ -1904,7 +1902,7 @@ static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename,
|
||||
}
|
||||
|
||||
if (sftp->rename_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) sftp->rename_packet,
|
||||
rc = _libssh2_channel_write(channel, 0, sftp->rename_packet,
|
||||
sftp->rename_s - sftp->rename_packet);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
@ -2027,7 +2025,7 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
|
||||
}
|
||||
|
||||
if (sftp->fstatvfs_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) packet, packet_len);
|
||||
rc = _libssh2_channel_write(channel, 0, packet, packet_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN || (0 <= rc && rc < packet_len)) {
|
||||
sftp->fstatvfs_packet = packet;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
@ -2139,7 +2137,7 @@ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
|
||||
}
|
||||
|
||||
if (sftp->statvfs_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) packet, packet_len);
|
||||
rc = _libssh2_channel_write(channel, 0, packet, packet_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN || (0 <= rc && rc < packet_len)) {
|
||||
sftp->statvfs_packet = packet;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
@ -2259,7 +2257,7 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
|
||||
}
|
||||
|
||||
if (sftp->mkdir_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) packet, packet_len);
|
||||
rc = _libssh2_channel_write(channel, 0, packet, packet_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
sftp->mkdir_packet = packet;
|
||||
return rc;
|
||||
@ -2352,7 +2350,7 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path,
|
||||
}
|
||||
|
||||
if (sftp->rmdir_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) sftp->rmdir_packet,
|
||||
rc = _libssh2_channel_write(channel, 0, sftp->rmdir_packet,
|
||||
packet_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
@ -2466,8 +2464,7 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
|
||||
}
|
||||
|
||||
if (sftp->stat_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) sftp->stat_packet,
|
||||
packet_len);
|
||||
rc = _libssh2_channel_write(channel, 0, sftp->stat_packet, packet_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
} else if (packet_len != rc) {
|
||||
@ -2596,7 +2593,7 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
|
||||
}
|
||||
|
||||
if (sftp->symlink_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_channel_write(channel, 0, (char *) sftp->symlink_packet,
|
||||
rc = _libssh2_channel_write(channel, 0, sftp->symlink_packet,
|
||||
packet_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return rc;
|
||||
|
@ -54,7 +54,7 @@
|
||||
#define UNPRINTABLE_CHAR '.'
|
||||
static void
|
||||
debugdump(LIBSSH2_SESSION * session,
|
||||
const char *desc, unsigned char *ptr, size_t size)
|
||||
const char *desc, const unsigned char *ptr, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
@ -598,8 +598,8 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
}
|
||||
|
||||
static int
|
||||
send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
size_t data_len, ssize_t * ret)
|
||||
send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
|
||||
size_t data_len, ssize_t *ret)
|
||||
{
|
||||
ssize_t rc;
|
||||
ssize_t length;
|
||||
@ -661,26 +661,30 @@ send_existing(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
}
|
||||
|
||||
/*
|
||||
* libssh2_transport_write
|
||||
* libssh2_transport_send
|
||||
*
|
||||
* Send a packet, encrypting it and adding a MAC code if necessary
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*
|
||||
* The data is provided as _two_ data areas that are combined by this
|
||||
* function. The 'data' part is sent immediately before 'data2'. 'data2' may
|
||||
* be set to NULL to only use a single part.
|
||||
*
|
||||
* Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
|
||||
* not sent yet. If it does so, the caller should call this function again as
|
||||
* soon as it is likely that more data can be sent, and this function MUST
|
||||
* then be called with the same argument set (same data pointer and same
|
||||
* data_len) until ERROR_NONE or failure is returned.
|
||||
*
|
||||
* This function DOES not call _libssh2_error() on any errors.
|
||||
* This function DOES NOT call _libssh2_error() on any errors.
|
||||
*/
|
||||
int
|
||||
_libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
size_t data_len)
|
||||
int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
const unsigned char *data, size_t data_len,
|
||||
const unsigned char *data2, size_t data2_len)
|
||||
{
|
||||
int blocksize =
|
||||
(session->state & LIBSSH2_STATE_NEWKEYS) ? session->local.crypt->
|
||||
blocksize : 8;
|
||||
(session->state & LIBSSH2_STATE_NEWKEYS) ?
|
||||
session->local.crypt->blocksize : 8;
|
||||
int padding_length;
|
||||
int packet_length;
|
||||
int total_length;
|
||||
@ -693,17 +697,15 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
int i;
|
||||
ssize_t ret;
|
||||
int rc;
|
||||
unsigned char *orgdata = data;
|
||||
const unsigned char *orgdata = data;
|
||||
size_t orgdata_len = data_len;
|
||||
|
||||
if(data_len >= (MAX_SSH_PACKET_LEN-0x100))
|
||||
/* too large packet, return error for this until we make this function
|
||||
split it up and send multiple SSH packets */
|
||||
return LIBSSH2_ERROR_INVAL;
|
||||
|
||||
debugdump(session, "libssh2_transport_write plain", data, data_len);
|
||||
if(data2)
|
||||
debugdump(session, "libssh2_transport_write plain2", data2, data2_len);
|
||||
|
||||
/* FIRST, check if we have a pending write to complete */
|
||||
/* FIRST, check if we have a pending write to complete. send_existing
|
||||
only sanity-check data and data_len and not data2 and data2_len!! */
|
||||
rc = send_existing(session, data, data_len, &ret);
|
||||
if (rc)
|
||||
return rc;
|
||||
@ -717,20 +719,51 @@ _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
|
||||
|
||||
if (encrypted && session->local.comp->compress) {
|
||||
/* the idea here is that these function must fail if the output gets
|
||||
larger than what fits in the assigned buffer so thus they don't
|
||||
check the input size as we don't know how much it compresses */
|
||||
size_t dest_len = MAX_SSH_PACKET_LEN-5-256;
|
||||
size_t dest2_len = dest_len;
|
||||
|
||||
/* compress directly to the target buffer */
|
||||
rc = session->local.comp->comp(session,
|
||||
data, &data_len,
|
||||
&p->outbuf[5], MAX_SSH_PACKET_LEN-5,
|
||||
&p->outbuf[5], &dest_len,
|
||||
data, data_len,
|
||||
&session->local.comp_abstract);
|
||||
if(rc)
|
||||
return rc; /* compression failure */
|
||||
|
||||
if(data2 && data2_len) {
|
||||
/* compress directly to the target buffer right after where the
|
||||
previous call put data */
|
||||
dest2_len -= dest_len;
|
||||
|
||||
rc = session->local.comp->comp(session,
|
||||
&p->outbuf[5+dest_len], &dest2_len,
|
||||
data2, data2_len,
|
||||
&session->local.comp_abstract);
|
||||
}
|
||||
else
|
||||
dest2_len = 0;
|
||||
if(rc)
|
||||
return rc; /* compression failure */
|
||||
|
||||
data = p->outbuf;
|
||||
/* data_len is already updated by the compression function */
|
||||
data_len = dest_len + dest2_len; /* use the combined length */
|
||||
}
|
||||
else
|
||||
else {
|
||||
if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN-0x100))
|
||||
/* too large packet, return error for this until we make this
|
||||
function split it up and send multiple SSH packets */
|
||||
return LIBSSH2_ERROR_INVAL;
|
||||
|
||||
/* copy the payload data */
|
||||
memcpy(&p->outbuf[5], data, data_len);
|
||||
if(data2 && data2_len)
|
||||
memcpy(&p->outbuf[5+data_len], data2, data2_len);
|
||||
data_len += data2_len; /* use the combined length */
|
||||
}
|
||||
|
||||
|
||||
/* RFC4253 says: Note that the length of the concatenation of
|
||||
'packet_length', 'padding_length', 'payload', and 'random padding'
|
||||
|
@ -44,23 +44,29 @@
|
||||
#include "libssh2_priv.h"
|
||||
#include "packet.h"
|
||||
|
||||
|
||||
/*
|
||||
* libssh2_transport_write
|
||||
* libssh2_transport_send
|
||||
*
|
||||
* Send a packet, encrypting it and adding a MAC code if necessary
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*
|
||||
* Returns PACKET_EAGAIN if it would block - and if it does so, you should
|
||||
* call this function again as soon as it is likely that more data can be
|
||||
* 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.
|
||||
* The data is provided as _two_ data areas that are combined by this
|
||||
* function. The 'data' part is sent immediately before 'data2'. 'data2' can
|
||||
* be set to NULL (or data2_len to 0) to only use a single part.
|
||||
*
|
||||
* NOTE: this function does not verify that 'data_len' is less than ~35000
|
||||
* which is what all implementations should support at least as packet size.
|
||||
* (RFC4253 section 6.1)
|
||||
* Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
|
||||
* not sent yet. If it does so, the caller should call this function again as
|
||||
* soon as it is likely that more data can be sent, and this function MUST
|
||||
* then be called with the same argument set (same data pointer and same
|
||||
* data_len) until ERROR_NONE or failure is returned.
|
||||
*
|
||||
* This function DOES NOT call _libssh2_error() on any errors.
|
||||
*/
|
||||
int _libssh2_transport_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
size_t data_len);
|
||||
int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
const unsigned char *data, size_t data_len,
|
||||
const unsigned char *data2, size_t data2_len);
|
||||
|
||||
/*
|
||||
* _libssh2_transport_read
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2005 Mikhail Gusarov <dottedmag@dottedmag.net>
|
||||
* Copyright (c) 2009 by Daniel Stenberg
|
||||
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
@ -89,14 +89,15 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
|
||||
*(s++) = SSH_MSG_USERAUTH_REQUEST;
|
||||
_libssh2_store_str(&s, username, username_len);
|
||||
_libssh2_store_str(&s, "ssh-connection", 14);
|
||||
_libssh2_store_str(&s, "none", 4);
|
||||
_libssh2_store_u32(&s, 4); /* send "none" separately */
|
||||
|
||||
session->userauth_list_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
if (session->userauth_list_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, session->userauth_list_data,
|
||||
session->userauth_list_data_len);
|
||||
rc = _libssh2_transport_send(session, session->userauth_list_data,
|
||||
session->userauth_list_data_len,
|
||||
(unsigned char *)"none", 4);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block requesting userauth list");
|
||||
@ -192,9 +193,9 @@ libssh2_userauth_authenticated(LIBSSH2_SESSION * session)
|
||||
* Plain ol' login
|
||||
*/
|
||||
static int
|
||||
userauth_password(LIBSSH2_SESSION *session, const char *username,
|
||||
unsigned int username_len, const char *password,
|
||||
unsigned int password_len,
|
||||
userauth_password(LIBSSH2_SESSION *session,
|
||||
const char *username, unsigned int username_len,
|
||||
const unsigned char *password, unsigned int password_len,
|
||||
LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)))
|
||||
{
|
||||
unsigned char *s;
|
||||
@ -213,10 +214,12 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
|
||||
* 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_data_len = username_len + 40;
|
||||
|
||||
session->userauth_pswd_data0 = ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ;
|
||||
|
||||
/* TODO: remove this alloc with a fixed buffer in the session
|
||||
struct */
|
||||
s = session->userauth_pswd_data =
|
||||
LIBSSH2_ALLOC(session, session->userauth_pswd_data_len);
|
||||
if (!session->userauth_pswd_data) {
|
||||
@ -230,7 +233,8 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
|
||||
_libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1);
|
||||
_libssh2_store_str(&s, "password", sizeof("password") - 1);
|
||||
*s++ = '\0';
|
||||
_libssh2_store_str(&s, password, password_len);
|
||||
_libssh2_store_u32(&s, password_len);
|
||||
/* 'password' is sent separately */
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
|
||||
"Attempting to login using password authentication");
|
||||
@ -239,8 +243,9 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
|
||||
}
|
||||
|
||||
if (session->userauth_pswd_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, session->userauth_pswd_data,
|
||||
session->userauth_pswd_data_len);
|
||||
rc = _libssh2_transport_send(session, session->userauth_pswd_data,
|
||||
session->userauth_pswd_data_len,
|
||||
password, password_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block writing password request");
|
||||
@ -335,8 +340,7 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
|
||||
|
||||
/* basic data_len + newpw_len(4) */
|
||||
session->userauth_pswd_data_len =
|
||||
username_len + password_len + 44 +
|
||||
session->userauth_pswd_newpw_len;
|
||||
username_len + password_len + 44;
|
||||
|
||||
s = session->userauth_pswd_data =
|
||||
LIBSSH2_ALLOC(session,
|
||||
@ -358,18 +362,21 @@ userauth_password(LIBSSH2_SESSION *session, const char *username,
|
||||
_libssh2_store_str(&s, "password",
|
||||
sizeof("password") - 1);
|
||||
*s++ = 0x01;
|
||||
_libssh2_store_str(&s, password, password_len);
|
||||
_libssh2_store_str(&s, session->userauth_pswd_newpw,
|
||||
_libssh2_store_str(&s, (char *)password, password_len);
|
||||
_libssh2_store_u32(&s,
|
||||
session->userauth_pswd_newpw_len);
|
||||
/* send session->userauth_pswd_newpw separately */
|
||||
|
||||
session->userauth_pswd_state = libssh2_NB_state_sent2;
|
||||
}
|
||||
|
||||
if (session->userauth_pswd_state == libssh2_NB_state_sent2) {
|
||||
rc = _libssh2_transport_write(session,
|
||||
session->userauth_pswd_data,
|
||||
session->
|
||||
userauth_pswd_data_len);
|
||||
rc = _libssh2_transport_send(session,
|
||||
session->userauth_pswd_data,
|
||||
session->userauth_pswd_data_len,
|
||||
(unsigned char *)
|
||||
session->userauth_pswd_newpw,
|
||||
session->userauth_pswd_newpw_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block waiting");
|
||||
@ -429,7 +436,7 @@ libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username,
|
||||
int rc;
|
||||
BLOCK_ADJUST(rc, session,
|
||||
userauth_password(session, username, username_len,
|
||||
password, password_len,
|
||||
(unsigned char *)password, password_len,
|
||||
passwd_change_cb));
|
||||
return rc;
|
||||
}
|
||||
@ -776,9 +783,10 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
if (session->userauth_host_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, session->userauth_host_packet,
|
||||
session->userauth_host_s -
|
||||
session->userauth_host_packet);
|
||||
rc = _libssh2_transport_send(session, session->userauth_host_packet,
|
||||
session->userauth_host_s -
|
||||
session->userauth_host_packet,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
|
||||
}
|
||||
@ -964,7 +972,8 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||
|
||||
_libssh2_store_str(&s, (const char *)session->userauth_pblc_method,
|
||||
session->userauth_pblc_method_len);
|
||||
_libssh2_store_str(&s, (const char *)pubkeydata, pubkeydata_len);
|
||||
_libssh2_store_u32(&s, pubkeydata_len);
|
||||
/* send pubkeydata separately */
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
|
||||
"Attempting publickey authentication");
|
||||
|
||||
@ -972,8 +981,9 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
if (session->userauth_pblc_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, session->userauth_pblc_packet,
|
||||
session->userauth_pblc_packet_len);
|
||||
rc = _libssh2_transport_send(session, session->userauth_pblc_packet,
|
||||
session->userauth_pblc_packet_len,
|
||||
pubkeydata, pubkeydata_len);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
|
||||
else if (rc) {
|
||||
@ -1130,9 +1140,10 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||
}
|
||||
|
||||
if (session->userauth_pblc_state == libssh2_NB_state_sent2) {
|
||||
rc = _libssh2_transport_write(session, session->userauth_pblc_packet,
|
||||
session->userauth_pblc_s -
|
||||
session->userauth_pblc_packet);
|
||||
rc = _libssh2_transport_send(session, session->userauth_pblc_packet,
|
||||
session->userauth_pblc_s -
|
||||
session->userauth_pblc_packet,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
|
||||
} else if (rc) {
|
||||
@ -1348,8 +1359,9 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
||||
}
|
||||
|
||||
if (session->userauth_kybd_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_transport_write(session, session->userauth_kybd_data,
|
||||
session->userauth_kybd_packet_len);
|
||||
rc = _libssh2_transport_send(session, session->userauth_kybd_data,
|
||||
session->userauth_kybd_packet_len,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
|
||||
} else if (rc) {
|
||||
@ -1551,8 +1563,9 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
||||
}
|
||||
|
||||
if (session->userauth_kybd_state == libssh2_NB_state_sent1) {
|
||||
rc = _libssh2_transport_write(session, session->userauth_kybd_data,
|
||||
session->userauth_kybd_packet_len);
|
||||
rc = _libssh2_transport_send(session, session->userauth_kybd_data,
|
||||
session->userauth_kybd_packet_len,
|
||||
NULL, 0);
|
||||
if (rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
|
||||
"Would block");
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user