Phase II of packet loop migration: Clean code is good code
This commit is contained in:
parent
5d9c0d50f3
commit
d3f854c21b
260
src/channel.c
260
src/channel.c
@ -106,6 +106,7 @@ LIBSSH2_CHANNEL *libssh2_channel_locate(LIBSSH2_SESSION *session, unsigned long
|
||||
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, char *channel_type, int channel_type_len, int window_size, int packet_size,
|
||||
char *message, int message_len)
|
||||
{
|
||||
unsigned char reply_codes[3] = { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, SSH_MSG_CHANNEL_OPEN_FAILURE, 0 };
|
||||
LIBSSH2_CHANNEL *channel = NULL;
|
||||
unsigned long local_channel = libssh2_channel_nextid(session);
|
||||
unsigned char *s, *packet = NULL;
|
||||
@ -113,7 +114,6 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
|
||||
window_size(4) + packet_size(4) */
|
||||
unsigned char *data = NULL;
|
||||
unsigned long data_len;
|
||||
int polls = 0;
|
||||
|
||||
channel = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_CHANNEL));
|
||||
if (!channel) {
|
||||
@ -161,35 +161,25 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_open_ex(LIBSSH2_SESSION *session, c
|
||||
goto channel_error;
|
||||
}
|
||||
|
||||
while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
if (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &data, &data_len, 1, packet + 5 + channel_type_len, 4, 1) == 0) {
|
||||
/* YAY! You like me! */
|
||||
break;
|
||||
}
|
||||
if (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_OPEN_FAILURE, &data, &data_len, 1, packet + 5 + channel_type_len, 4, 0) == 0) {
|
||||
/* But! Dear! I thought we had something! */
|
||||
|
||||
/* TODO: provide reason code and description */
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Channel open failure", 0);
|
||||
goto channel_error;
|
||||
}
|
||||
usleep(LIBSSH2_SOCKET_POLL_UDELAY);
|
||||
if (polls++ > LIBSSH2_SOCKET_POLL_MAXLOOPS) {
|
||||
/* Give up waiting */
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, "Timed out waiting for response", 0);
|
||||
goto channel_error;
|
||||
}
|
||||
if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, packet + 5 + channel_type_len, 4)) {
|
||||
goto channel_error;
|
||||
}
|
||||
|
||||
channel->remote.id = libssh2_ntohu32(data + 5);
|
||||
channel->local.window_size = libssh2_ntohu32(data + 9);
|
||||
channel->local.window_size_initial = libssh2_ntohu32(data + 9);
|
||||
channel->local.packet_size = libssh2_ntohu32(data + 13);
|
||||
if (data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) {
|
||||
channel->remote.id = libssh2_ntohu32(data + 5);
|
||||
channel->local.window_size = libssh2_ntohu32(data + 9);
|
||||
channel->local.window_size_initial = libssh2_ntohu32(data + 9);
|
||||
channel->local.packet_size = libssh2_ntohu32(data + 13);
|
||||
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, data);
|
||||
|
||||
return channel;
|
||||
return channel;
|
||||
}
|
||||
|
||||
if (data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, "Channel open failure", 0);
|
||||
}
|
||||
|
||||
channel_error:
|
||||
|
||||
@ -265,7 +255,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *se
|
||||
*/
|
||||
LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, char *host, int port, int *bound_port, int queue_maxsize)
|
||||
{
|
||||
unsigned char *packet, *s;
|
||||
unsigned char *packet, *s, *data, reply_codes[3] = { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 };
|
||||
unsigned long data_len;
|
||||
unsigned long host_len = (host ? strlen(host) : (sizeof("0.0.0.0") - 1));
|
||||
unsigned long packet_len = host_len + (sizeof("tcpip-forward") - 1) + 14;
|
||||
/* packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + port(4) */
|
||||
@ -292,59 +283,58 @@ LIBSSH2_API LIBSSH2_LISTENER *libssh2_channel_forward_listen_ex(LIBSSH2_SESSION
|
||||
}
|
||||
LIBSSH2_FREE(session, packet);
|
||||
|
||||
while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_REQUEST_SUCCESS, &data, &data_len, 1) == 0) {
|
||||
LIBSSH2_LISTENER *listener;
|
||||
|
||||
listener = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_LISTENER));
|
||||
if (!listener) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue", 0);
|
||||
LIBSSH2_FREE(session, data);
|
||||
return NULL;
|
||||
}
|
||||
memset(listener, 0, sizeof(LIBSSH2_LISTENER));
|
||||
listener->session = session;
|
||||
listener->host = LIBSSH2_ALLOC(session, host_len + 1);
|
||||
if (!listener->host) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue", 0);
|
||||
LIBSSH2_FREE(session, listener);
|
||||
LIBSSH2_FREE(session, data);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(listener->host, host ? host : "0.0.0.0", host_len);
|
||||
listener->host[host_len] = 0;
|
||||
if (data_len >= 5 && !port) {
|
||||
listener->port = libssh2_ntohu32(data + 1);
|
||||
} else {
|
||||
listener->port = port;
|
||||
}
|
||||
|
||||
listener->queue_size = 0;
|
||||
listener->queue_maxsize = queue_maxsize;
|
||||
|
||||
listener->next = session->listeners;
|
||||
listener->prev = NULL;
|
||||
if (session->listeners) {
|
||||
session->listeners->prev = listener;
|
||||
}
|
||||
session->listeners = listener;
|
||||
|
||||
if (bound_port) {
|
||||
*bound_port = listener->port;
|
||||
}
|
||||
if (data[0] == SSH_MSG_REQUEST_SUCCESS) {
|
||||
LIBSSH2_LISTENER *listener;
|
||||
|
||||
listener = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_LISTENER));
|
||||
if (!listener) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue", 0);
|
||||
LIBSSH2_FREE(session, data);
|
||||
return listener;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_REQUEST_FAILURE, &data, &data_len, 0) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED, "Unable to complete request for forward-listen", 0);
|
||||
return NULL;
|
||||
}
|
||||
memset(listener, 0, sizeof(LIBSSH2_LISTENER));
|
||||
listener->session = session;
|
||||
listener->host = LIBSSH2_ALLOC(session, host_len + 1);
|
||||
if (!listener->host) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for listener queue", 0);
|
||||
LIBSSH2_FREE(session, listener);
|
||||
LIBSSH2_FREE(session, data);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(listener->host, host ? host : "0.0.0.0", host_len);
|
||||
listener->host[host_len] = 0;
|
||||
if (data_len >= 5 && !port) {
|
||||
listener->port = libssh2_ntohu32(data + 1);
|
||||
} else {
|
||||
listener->port = port;
|
||||
}
|
||||
|
||||
listener->queue_size = 0;
|
||||
listener->queue_maxsize = queue_maxsize;
|
||||
|
||||
listener->next = session->listeners;
|
||||
listener->prev = NULL;
|
||||
if (session->listeners) {
|
||||
session->listeners->prev = listener;
|
||||
}
|
||||
session->listeners = listener;
|
||||
|
||||
if (bound_port) {
|
||||
*bound_port = listener->port;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
return listener;
|
||||
}
|
||||
|
||||
if (data[0] == SSH_MSG_REQUEST_FAILURE) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED, "Unable to complete request for forward-listen", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -451,7 +441,8 @@ LIBSSH2_API LIBSSH2_CHANNEL *libssh2_channel_forward_accept(LIBSSH2_LISTENER *li
|
||||
LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varname, int varname_len, char *value, int value_len)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
unsigned char *s, *packet;
|
||||
unsigned char *s, *packet, *data, reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }, local_channel[4];
|
||||
unsigned long data_len;
|
||||
unsigned long packet_len = varname_len + value_len + 21; /* packet_type(1) + channel_id(4) + request_len(4) + request(3)"env" +
|
||||
want_reply(1) + varname_len(4) + value_len(4) */
|
||||
|
||||
@ -481,26 +472,18 @@ LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, char *varnam
|
||||
}
|
||||
LIBSSH2_FREE(session, packet);
|
||||
|
||||
while (1) {
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
unsigned char local_channel[4];
|
||||
|
||||
libssh2_htonu32(local_channel, channel->local.id);
|
||||
|
||||
if (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_SUCCESS, &data, &data_len, 1, local_channel, 4, 1) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_FAILURE, &data, &data_len, 1, local_channel, 4, 0) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel-setenv", 0);
|
||||
return -1;
|
||||
}
|
||||
libssh2_htonu32(local_channel, channel->local.id);
|
||||
if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Never reached, just giving the compiler something to not complain about */
|
||||
if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel-setenv", 0);
|
||||
return -1;
|
||||
}
|
||||
/* }}} */
|
||||
@ -514,7 +497,8 @@ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, char *t
|
||||
int width_px, int height_px)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
unsigned char *s, *packet;
|
||||
unsigned char *s, *packet, *data, reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }, local_channel[4];
|
||||
unsigned long data_len;
|
||||
unsigned long packet_len = term_len + modes_len + 41; /* packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) + want_reply(1) +
|
||||
term_len(4) + width(4) + height(4) + width_px(4) + height_px(4) + modes_len(4) */
|
||||
|
||||
@ -553,26 +537,18 @@ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, char *t
|
||||
}
|
||||
LIBSSH2_FREE(session, packet);
|
||||
|
||||
while (1) {
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
unsigned char local_channel[4];
|
||||
|
||||
libssh2_htonu32(local_channel, channel->local.id);
|
||||
|
||||
if (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_SUCCESS, &data, &data_len, 1, local_channel, 4, 1) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_FAILURE, &data, &data_len, 1, local_channel, 4, 1) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel request-pty", 0);
|
||||
return -1;
|
||||
}
|
||||
libssh2_htonu32(local_channel, channel->local.id);
|
||||
if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Never reached, just giving the compiler something to not complain about */
|
||||
if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel request-pty", 0);
|
||||
return -1;
|
||||
}
|
||||
/* }}} */
|
||||
@ -585,7 +561,8 @@ LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, char *t
|
||||
LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, char *auth_proto, char *auth_cookie, int screen_number)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
unsigned char *s, *packet;
|
||||
unsigned char *s, *packet, *data, reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }, local_channel[4];
|
||||
unsigned long data_len;
|
||||
unsigned long proto_len = auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1);
|
||||
unsigned long cookie_len = auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN;
|
||||
unsigned long packet_len = proto_len + cookie_len + 41; /* packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) + want_reply(1) +
|
||||
@ -632,26 +609,14 @@ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_
|
||||
}
|
||||
LIBSSH2_FREE(session, packet);
|
||||
|
||||
while (1) {
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
unsigned char local_channel[4];
|
||||
|
||||
libssh2_htonu32(local_channel, channel->local.id);
|
||||
|
||||
if (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_SUCCESS, &data, &data_len, 1, local_channel, 4, 1) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_FAILURE, &data, &data_len, 1, local_channel, 4, 1) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel x11-req", 0);
|
||||
return -1;
|
||||
}
|
||||
libssh2_htonu32(local_channel, channel->local.id);
|
||||
if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Never reached, just giving the compiler something to not complain about */
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel x11-req", 0);
|
||||
return -1;
|
||||
}
|
||||
/* }}} */
|
||||
@ -662,7 +627,8 @@ LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_
|
||||
LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, char *request, int request_len, char *message, int message_len)
|
||||
{
|
||||
LIBSSH2_SESSION *session = channel->session;
|
||||
unsigned char *s, *packet;
|
||||
unsigned char *s, *packet, *data, reply_codes[3] = { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }, local_channel[4];
|
||||
unsigned long data_len;
|
||||
unsigned long packet_len = request_len + 10; /* packet_type(1) + channel(4) + request_len(4) + want_reply(1) */
|
||||
|
||||
if (message) {
|
||||
@ -694,26 +660,18 @@ LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, char *
|
||||
}
|
||||
LIBSSH2_FREE(session, packet);
|
||||
|
||||
while (1) {
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
unsigned char local_channel[4];
|
||||
|
||||
libssh2_htonu32(local_channel, channel->local.id);
|
||||
|
||||
if (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_SUCCESS, &data, &data_len, 1, local_channel, 4, 1) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask_ex(session, SSH_MSG_CHANNEL_FAILURE, &data, &data_len, 1, local_channel, 4, 0) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel-process-startup", 0);
|
||||
return -1;
|
||||
}
|
||||
libssh2_htonu32(local_channel, channel->local.id);
|
||||
if (libssh2_packet_requirev_ex(session, reply_codes, &data, &data_len, 1, local_channel, 4)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Never reached, just giving the compiler something to not complain about */
|
||||
if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "Unable to complete request for channel-process-startup", 0);
|
||||
return -1;
|
||||
}
|
||||
/* }}} */
|
||||
|
294
src/userauth.c
294
src/userauth.c
@ -51,6 +51,7 @@
|
||||
*/
|
||||
LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, char *username, int username_len)
|
||||
{
|
||||
unsigned char reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
|
||||
unsigned long data_len = username_len + 31; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" +
|
||||
method_len(4) + method(4)"none" */
|
||||
unsigned long methods_len;
|
||||
@ -81,19 +82,15 @@ LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, char *username
|
||||
}
|
||||
LIBSSH2_FREE(session, data);
|
||||
|
||||
while (1) {
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_SUCCESS, &data, &data_len, 1) == 0) {
|
||||
/* Wow, who'dve thought... */
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return NULL;
|
||||
}
|
||||
if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_FAILURE, &data, &data_len, 0) == 0) {
|
||||
/* What we *actually* wanted to happen */
|
||||
break;
|
||||
}
|
||||
/* TODO: Timeout? */
|
||||
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
/* Wow, who'dve thought... */
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
methods_len = libssh2_ntohu32(data + 1);
|
||||
@ -121,7 +118,7 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, char *use
|
||||
char *password, int password_len,
|
||||
LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb)))
|
||||
{
|
||||
unsigned char *data, *s;
|
||||
unsigned char *data, *s, reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 };
|
||||
unsigned long data_len = username_len + password_len + 40; /* packet_type(1) + username_len(4) + service_len(4) + service(14)"ssh-connection" +
|
||||
method_len(4) + method(8)"password" + chgpwdbool(1) + password_len(4) */
|
||||
|
||||
@ -153,71 +150,72 @@ LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, char *use
|
||||
}
|
||||
LIBSSH2_FREE(session, data);
|
||||
|
||||
while (1) {
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_SUCCESS, &data, &data_len, 1) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_FAILURE, &data, &data_len, 0) == 0) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, &data, &data_len, 0) == 0) {
|
||||
char *newpw = NULL;
|
||||
int newpw_len = 0;
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
if (passwd_change_cb) {
|
||||
passwd_change_cb(session, &newpw, &newpw_len, &session->abstract);
|
||||
if (!newpw) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password expired, and callback failed", 0);
|
||||
return -1;
|
||||
}
|
||||
data_len = username_len + password_len + 44 + newpw_len; /* basic data_len + newpw_len(4) */
|
||||
s = data = LIBSSH2_ALLOC(session, data_len);
|
||||
if (!data) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth-password-change request", 0);
|
||||
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, 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;
|
||||
|
||||
*s = 0xFF; s++;
|
||||
|
||||
libssh2_htonu32(s, password_len); s += 4;
|
||||
memcpy(s, password, password_len); s += password_len;
|
||||
|
||||
libssh2_htonu32(s, newpw_len); s += 4;
|
||||
memcpy(s, newpw, newpw_len); s += newpw_len;
|
||||
|
||||
if (libssh2_packet_write(session, data, data_len)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password-change request", 0);
|
||||
LIBSSH2_FREE(session, data);
|
||||
return -1;
|
||||
}
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, newpw);
|
||||
/* TODO: Reset timeout? */
|
||||
} else {
|
||||
libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password Expired, and no callback specified", 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* TODO: Timeout? */
|
||||
password_response:
|
||||
if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data[0] == SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) {
|
||||
char *newpw = NULL;
|
||||
int newpw_len = 0;
|
||||
|
||||
LIBSSH2_FREE(session, data);
|
||||
if (passwd_change_cb) {
|
||||
passwd_change_cb(session, &newpw, &newpw_len, &session->abstract);
|
||||
if (!newpw) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password expired, and callback failed", 0);
|
||||
return -1;
|
||||
}
|
||||
data_len = username_len + password_len + 44 + newpw_len; /* basic data_len + newpw_len(4) */
|
||||
s = data = LIBSSH2_ALLOC(session, data_len);
|
||||
if (!data) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_ALLOC, "Unable to allocate memory for userauth-password-change request", 0);
|
||||
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, 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;
|
||||
|
||||
*s = 0xFF; s++;
|
||||
|
||||
libssh2_htonu32(s, password_len); s += 4;
|
||||
memcpy(s, password, password_len); s += password_len;
|
||||
|
||||
libssh2_htonu32(s, newpw_len); s += 4;
|
||||
memcpy(s, newpw, newpw_len); s += newpw_len;
|
||||
|
||||
if (libssh2_packet_write(session, data, data_len)) {
|
||||
libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, "Unable to send userauth-password-change request", 0);
|
||||
LIBSSH2_FREE(session, data);
|
||||
return -1;
|
||||
}
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, newpw);
|
||||
|
||||
/* Ugliest use of goto ever. Blame it on the askN => requirev migration. */
|
||||
goto password_response;
|
||||
} else {
|
||||
libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, "Password Expired, and no callback specified", 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* FAILURE */
|
||||
LIBSSH2_FREE(session, data);
|
||||
return -1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -344,8 +342,8 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
void *abstract;
|
||||
unsigned char buf[5];
|
||||
struct iovec datavec[4];
|
||||
unsigned char *method, *pubkeydata, *packet, *s, *sig;
|
||||
unsigned long method_len, pubkeydata_len, packet_len, sig_len;
|
||||
unsigned char *method, *pubkeydata, *packet, *s, *sig, *data, reply_codes[3] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 };
|
||||
unsigned long method_len, pubkeydata_len, packet_len, sig_len, data_len;
|
||||
|
||||
if (libssh2_file_read_publickey(session, &method, &method_len, &pubkeydata, &pubkeydata_len, publickey)) {
|
||||
return -1;
|
||||
@ -438,27 +436,21 @@ LIBSSH2_API int libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
}
|
||||
LIBSSH2_FREE(session, packet);
|
||||
|
||||
while (1) {
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_SUCCESS, &data, &data_len, 1) == 0) {
|
||||
/* We are us and we've proved it. */
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_FAILURE, &data, &data_len, 0) == 0) {
|
||||
/* This public key is not allowed for this user on this server */
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid signature for supplied public key, or bad username/public key combination", 0);
|
||||
return -1;
|
||||
}
|
||||
/* TODO: Timeout? */
|
||||
if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
/* We are us and we've proved it. */
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This public key is not allowed for this user on this server */
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid signature for supplied public key, or bad username/public key combination", 0);
|
||||
return -1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -473,8 +465,9 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
void *abstract;
|
||||
unsigned char buf[5];
|
||||
struct iovec datavec[4];
|
||||
unsigned char *method, *pubkeydata, *packet, *s, *b, *sig;
|
||||
unsigned long method_len, pubkeydata_len, packet_len, sig_len;
|
||||
unsigned char *method, *pubkeydata, *packet, *s, *b, *sig, *data;
|
||||
unsigned char reply_codes[4] = { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_PK_OK, 0 };
|
||||
unsigned long method_len, pubkeydata_len, packet_len, sig_len, data_len;
|
||||
|
||||
if (libssh2_file_read_publickey(session, &method, &method_len, &pubkeydata, &pubkeydata_len, publickey)) {
|
||||
return -1;
|
||||
@ -515,45 +508,35 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_SUCCESS, &data, &data_len, 1) == 0) {
|
||||
/* God help any SSH server that allows an UNVERIFIED public key to validate the user */
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, method);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_FAILURE, &data, &data_len, 0) == 0) {
|
||||
/* This public key is not allowed for this user on this server */
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, method);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED, "Username/PublicKey combination invalid", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_PK_OK, &data, &data_len, 0) == 0) {
|
||||
/* Semi-Success! */
|
||||
if ((libssh2_ntohu32(data + 1) != method_len) ||
|
||||
strncmp(data + 5, method, method_len) ||
|
||||
(libssh2_ntohu32(data + 5 + method_len) != pubkeydata_len) ||
|
||||
strncmp(data + 5 + method_len + 4, pubkeydata, pubkeydata_len)) {
|
||||
/* Unlikely but possible, the server has responded to a different userauth public key request */
|
||||
LIBSSH2_FREE(session, data);
|
||||
continue;
|
||||
}
|
||||
LIBSSH2_FREE(session, data);
|
||||
break;
|
||||
}
|
||||
/* TODO: Timeout? */
|
||||
if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) {
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, method);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
/* God help any SSH server that allows an UNVERIFIED public key to validate the user */
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, method);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data[0] == SSH_MSG_USERAUTH_FAILURE) {
|
||||
/* This public key is not allowed for this user on this server */
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, packet);
|
||||
LIBSSH2_FREE(session, method);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED, "Username/PublicKey combination invalid", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Semi-Success! */
|
||||
LIBSSH2_FREE(session, data);
|
||||
LIBSSH2_FREE(session, pubkeydata);
|
||||
|
||||
if (libssh2_file_read_privatekey(session, &privkeyobj, &abstract, method, method_len, privatekey, passphrase)) {
|
||||
@ -614,26 +597,23 @@ LIBSSH2_API int libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session,
|
||||
}
|
||||
LIBSSH2_FREE(session, packet);
|
||||
|
||||
while (1) {
|
||||
unsigned char *data;
|
||||
unsigned long data_len;
|
||||
/* PK_OK is no longer valid */
|
||||
reply_codes[2] = 0;
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_SUCCESS, &data, &data_len, 1) == 0) {
|
||||
/* We are us and we've proved it. */
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (libssh2_packet_ask(session, SSH_MSG_USERAUTH_FAILURE, &data, &data_len, 0) == 0) {
|
||||
/* This public key is not allowed for this user on this server */
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid signature for supplied public key, or bad username/public key combination", 0);
|
||||
return -1;
|
||||
}
|
||||
/* TODO: Timeout? */
|
||||
if (libssh2_packet_requirev(session, reply_codes, &data, &data_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
if (data[0] == SSH_MSG_USERAUTH_SUCCESS) {
|
||||
/* We are us and we've proved it. */
|
||||
LIBSSH2_FREE(session, data);
|
||||
session->state |= LIBSSH2_STATE_AUTHENTICATED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This public key is not allowed for this user on this server */
|
||||
LIBSSH2_FREE(session, data);
|
||||
libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "Invalid signature for supplied public key, or bad username/public key combination", 0);
|
||||
return -1;
|
||||
}
|
||||
/* }}} */
|
||||
|
Loading…
Reference in New Issue
Block a user