summaryrefslogtreecommitdiff
path: root/libs/libssh2/src/publickey.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libssh2/src/publickey.c')
-rw-r--r--libs/libssh2/src/publickey.c523
1 files changed, 371 insertions, 152 deletions
diff --git a/libs/libssh2/src/publickey.c b/libs/libssh2/src/publickey.c
index bfee0a8420..f26c6327dc 100644
--- a/libs/libssh2/src/publickey.c
+++ b/libs/libssh2/src/publickey.c
@@ -60,7 +60,7 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST 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} ,
+ sizeof("publickey") - 1},
{0, NULL, 0}
};
@@ -78,13 +78,13 @@ static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_response_codes[] =
#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8
static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_status_codes[] = {
- {LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1} ,
+ {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} ,
+ sizeof("storage exceeded") - 1},
{LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported",
- sizeof("version not supported") - 1} ,
+ 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",
@@ -110,13 +110,14 @@ publickey_status_error(const LIBSSH2_PUBLICKEY *pkey,
const char *msg;
/* GENERAL_FAILURE got remapped between version 1 and 2 */
- if (status == 6 && pkey && pkey->version == 1) {
+ if(status == 6 && pkey && pkey->version == 1) {
status = 7;
}
- if (status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) {
+ if(status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) {
msg = "unknown";
- } else {
+ }
+ else {
msg = publickey_status_codes[status].name;
}
@@ -139,11 +140,12 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
*data = NULL; /* default to nothing returned */
*data_len = 0;
- if (pkey->receive_state == libssh2_NB_state_idle) {
+ if(pkey->receive_state == libssh2_NB_state_idle) {
rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc != 4) {
+ }
+ else if(rc != 4) {
return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid response from publickey subsystem");
}
@@ -151,7 +153,7 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
pkey->receive_packet_len = _libssh2_ntohu32(buffer);
pkey->receive_packet =
LIBSSH2_ALLOC(session, pkey->receive_packet_len);
- if (!pkey->receive_packet) {
+ if(!pkey->receive_packet) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate publickey response "
"buffer");
@@ -160,12 +162,13 @@ publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey,
pkey->receive_state = libssh2_NB_state_sent;
}
- if (pkey->receive_state == libssh2_NB_state_sent) {
+ if(pkey->receive_state == libssh2_NB_state_sent) {
rc = _libssh2_channel_read(channel, 0, (char *) pkey->receive_packet,
pkey->receive_packet_len);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc != (int)pkey->receive_packet_len) {
+ }
+ else if(rc != (int)pkey->receive_packet_len) {
LIBSSH2_FREE(session, pkey->receive_packet);
pkey->receive_packet = NULL;
pkey->receive_state = libssh2_NB_state_idle;
@@ -195,20 +198,20 @@ publickey_response_id(unsigned char **pdata, size_t data_len)
unsigned char *data = *pdata;
const LIBSSH2_PUBLICKEY_CODE_LIST *codes = publickey_response_codes;
- if (data_len < 4) {
+ if(data_len < 4) {
/* Malformed response */
return -1;
}
response_len = _libssh2_ntohu32(data);
data += 4;
data_len -= 4;
- if (data_len < response_len) {
+ if(data_len < response_len) {
/* Malformed response */
return -1;
}
- while (codes->name) {
- if ((unsigned long)codes->name_len == response_len &&
+ while(codes->name) {
+ if((unsigned long)codes->name_len == response_len &&
strncmp(codes->name, (char *) data, response_len) == 0) {
*pdata = data + response_len;
return codes->code;
@@ -231,28 +234,41 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
size_t data_len;
int response;
- while (1) {
+ while(1) {
int rc = publickey_packet_receive(pkey, &data, &data_len);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ }
+ else if(rc) {
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from "
"publickey subsystem");
}
+ if(data_len < 4) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Publickey response too small");
+ }
+
s = data;
response = publickey_response_id(&s, data_len);
- switch (response) {
+ switch(response) {
case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
/* Error, or processing complete */
{
- unsigned long status = _libssh2_ntohu32(s);
+ unsigned long status = 0;
+
+ if(data_len < 8) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Publickey response too small");
+ }
+
+ status = _libssh2_ntohu32(s);
LIBSSH2_FREE(session, data);
- if (status == LIBSSH2_PUBLICKEY_SUCCESS)
+ if(status == LIBSSH2_PUBLICKEY_SUCCESS)
return 0;
publickey_status_error(pkey, session, status);
@@ -260,7 +276,7 @@ publickey_response_success(LIBSSH2_PUBLICKEY * pkey)
}
default:
LIBSSH2_FREE(session, data);
- if (response < 0) {
+ if(response < 0) {
return _libssh2_error(session,
LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response");
@@ -289,7 +305,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
int response;
int rc;
- if (session->pkeyInit_state == libssh2_NB_state_idle) {
+ if(session->pkeyInit_state == libssh2_NB_state_idle) {
session->pkeyInit_data = NULL;
session->pkeyInit_pkey = NULL;
session->pkeyInit_channel = NULL;
@@ -300,7 +316,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_allocated;
}
- if (session->pkeyInit_state == libssh2_NB_state_allocated) {
+ if(session->pkeyInit_state == libssh2_NB_state_allocated) {
session->pkeyInit_channel =
_libssh2_channel_open(session, "session",
@@ -308,8 +324,8 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
LIBSSH2_CHANNEL_WINDOW_DEFAULT,
LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL,
0);
- if (!session->pkeyInit_channel) {
- if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN)
+ if(!session->pkeyInit_channel) {
+ if(libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN)
/* The error state is already set, so leave it */
return NULL;
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
@@ -320,17 +336,18 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_sent;
}
- if (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,
"publickey",
sizeof("publickey") - 1);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting publickey subsystem");
return NULL;
- } else if (rc) {
+ }
+ else if(rc) {
_libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE,
"Unable to request publickey subsystem");
goto err_exit;
@@ -339,11 +356,11 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_sent1;
}
- if (session->pkeyInit_state == libssh2_NB_state_sent1) {
+ if(session->pkeyInit_state == libssh2_NB_state_sent1) {
unsigned char *s;
rc = _libssh2_channel_extended_data(session->pkeyInit_channel,
- LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE);
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block starting publickey subsystem");
return NULL;
@@ -351,7 +368,7 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_pkey =
LIBSSH2_CALLOC(session, sizeof(LIBSSH2_PUBLICKEY));
- if (!session->pkeyInit_pkey) {
+ if(!session->pkeyInit_pkey) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate a new publickey structure");
goto err_exit;
@@ -377,15 +394,16 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_sent2;
}
- if (session->pkeyInit_state == libssh2_NB_state_sent2) {
+ if(session->pkeyInit_state == libssh2_NB_state_sent2) {
rc = _libssh2_channel_write(session->pkeyInit_channel, 0,
session->pkeyInit_buffer,
19 - session->pkeyInit_buffer_sent);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block sending publickey version packet");
return NULL;
- } else if (rc < 0) {
+ }
+ else if(rc < 0) {
_libssh2_error(session, rc,
"Unable to send publickey version packet");
goto err_exit;
@@ -400,18 +418,19 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
session->pkeyInit_state = libssh2_NB_state_sent3;
}
- if (session->pkeyInit_state == libssh2_NB_state_sent3) {
- while (1) {
+ if(session->pkeyInit_state == libssh2_NB_state_sent3) {
+ while(1) {
unsigned char *s;
rc = publickey_packet_receive(session->pkeyInit_pkey,
&session->pkeyInit_data,
&session->pkeyInit_data_len);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for response from "
"publickey subsystem");
return NULL;
- } else if (rc) {
+ }
+ else if(rc) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from "
"publickey subsystem");
@@ -419,31 +438,62 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
}
s = session->pkeyInit_data;
- if ((response =
+ if((response =
publickey_response_id(&s, session->pkeyInit_data_len)) < 0) {
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Invalid publickey subsystem response code");
goto err_exit;
}
- switch (response) {
+ if(session->pkeyInit_data_len < 4) {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Public key init data too small");
+ goto err_exit;
+ }
+
+ switch(response) {
case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
/* Error */
{
unsigned long status, descr_len, lang_len;
- status = _libssh2_ntohu32(s);
- s += 4;
- descr_len = _libssh2_ntohu32(s);
- s += 4;
- /* description starts here */
- s += descr_len;
- lang_len = _libssh2_ntohu32(s);
- s += 4;
- /* lang starts here */
- s += lang_len;
-
- if (s >
+ if(session->pkeyInit_data_len >= 8) {
+ status = _libssh2_ntohu32(s);
+ s += 4;
+ descr_len = _libssh2_ntohu32(s);
+ s += 4;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Public key init data too small");
+ goto err_exit;
+ }
+
+ if(s + descr_len + 4 <=
+ session->pkeyInit_data + session->pkeyInit_data_len) {
+ /* description starts here */
+ s += descr_len;
+ lang_len = _libssh2_ntohu32(s);
+ s += 4;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Public key init data too small");
+ goto err_exit;
+ }
+
+ if(s + lang_len <=
+ session->pkeyInit_data + session->pkeyInit_data_len) {
+ /* lang starts here */
+ s += lang_len;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Public key init data too small");
+ goto err_exit;
+ }
+
+ if(s >
session->pkeyInit_data + session->pkeyInit_data_len) {
_libssh2_error(session,
LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
@@ -459,10 +509,11 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
case LIBSSH2_PUBLICKEY_RESPONSE_VERSION:
/* What we want */
session->pkeyInit_pkey->version = _libssh2_ntohu32(s);
- if (session->pkeyInit_pkey->version >
+ if(session->pkeyInit_pkey->version >
LIBSSH2_PUBLICKEY_VERSION) {
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY,
- "Truncate remote publickey version from %lu",
+ "Truncate remote publickey version "
+ "from %lu",
session->pkeyInit_pkey->version);
session->pkeyInit_pkey->version =
LIBSSH2_PUBLICKEY_VERSION;
@@ -489,19 +540,19 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
/* Never reached except by direct goto */
err_exit:
session->pkeyInit_state = libssh2_NB_state_sent4;
- if (session->pkeyInit_channel) {
+ if(session->pkeyInit_channel) {
rc = _libssh2_channel_close(session->pkeyInit_channel);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block closing channel");
return NULL;
}
}
- if (session->pkeyInit_pkey) {
+ if(session->pkeyInit_pkey) {
LIBSSH2_FREE(session, session->pkeyInit_pkey);
session->pkeyInit_pkey = NULL;
}
- if (session->pkeyInit_data) {
+ if(session->pkeyInit_data) {
LIBSSH2_FREE(session, session->pkeyInit_data);
session->pkeyInit_data = NULL;
}
@@ -553,16 +604,16 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
channel = pkey->channel;
session = channel->session;
- if (pkey->add_state == libssh2_NB_state_idle) {
+ if(pkey->add_state == libssh2_NB_state_idle) {
pkey->add_packet = NULL;
_libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, "Adding %s publickey",
name);
- if (pkey->version == 1) {
+ if(pkey->version == 1) {
for(i = 0; i < num_attrs; i++) {
/* Search for a comment attribute */
- if (attrs[i].name_len == (sizeof("comment") - 1) &&
+ if(attrs[i].name_len == (sizeof("comment") - 1) &&
strncmp(attrs[i].name, "comment",
sizeof("comment") - 1) == 0) {
comment = (unsigned char *) attrs[i].value;
@@ -571,7 +622,8 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
}
}
packet_len += 4 + comment_len;
- } else {
+ }
+ else {
packet_len += 5; /* overwrite(1) + attribute_count(4) */
for(i = 0; i < num_attrs; i++) {
packet_len += 9 + attrs[i].name_len + attrs[i].value_len;
@@ -580,7 +632,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
}
pkey->add_packet = LIBSSH2_ALLOC(session, packet_len);
- if (!pkey->add_packet) {
+ if(!pkey->add_packet) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey \"add\" packet");
@@ -593,10 +645,10 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
pkey->add_s += 4;
memcpy(pkey->add_s, "add", sizeof("add") - 1);
pkey->add_s += sizeof("add") - 1;
- if (pkey->version == 1) {
+ if(pkey->version == 1) {
_libssh2_htonu32(pkey->add_s, comment_len);
pkey->add_s += 4;
- if (comment) {
+ if(comment) {
memcpy(pkey->add_s, comment, comment_len);
pkey->add_s += comment_len;
}
@@ -609,7 +661,8 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
pkey->add_s += 4;
memcpy(pkey->add_s, blob, blob_len);
pkey->add_s += blob_len;
- } else {
+ }
+ else {
/* Version == 2 */
_libssh2_htonu32(pkey->add_s, name_len);
@@ -644,12 +697,13 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
pkey->add_state = libssh2_NB_state_created;
}
- if (pkey->add_state == libssh2_NB_state_created) {
+ if(pkey->add_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, pkey->add_packet,
(pkey->add_s - pkey->add_packet));
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if ((pkey->add_s - pkey->add_packet) != rc) {
+ }
+ else if((pkey->add_s - pkey->add_packet) != rc) {
LIBSSH2_FREE(session, pkey->add_packet);
pkey->add_packet = NULL;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
@@ -662,7 +716,7 @@ libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name,
}
rc = publickey_response_success(pkey);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
}
@@ -693,11 +747,11 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
channel = pkey->channel;
session = channel->session;
- if (pkey->remove_state == libssh2_NB_state_idle) {
+ if(pkey->remove_state == libssh2_NB_state_idle) {
pkey->remove_packet = NULL;
pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len);
- if (!pkey->remove_packet) {
+ if(!pkey->remove_packet) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey \"remove\" packet");
@@ -727,12 +781,13 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
pkey->remove_state = libssh2_NB_state_created;
}
- if (pkey->remove_state == libssh2_NB_state_created) {
+ if(pkey->remove_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, pkey->remove_packet,
(pkey->remove_s - pkey->remove_packet));
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if ((pkey->remove_s - pkey->remove_packet) != rc) {
+ }
+ else if((pkey->remove_s - pkey->remove_packet) != rc) {
LIBSSH2_FREE(session, pkey->remove_packet);
pkey->remove_packet = NULL;
pkey->remove_state = libssh2_NB_state_idle;
@@ -746,7 +801,7 @@ libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey,
}
rc = publickey_response_success(pkey);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
}
@@ -776,7 +831,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
channel = pkey->channel;
session = channel->session;
- if (pkey->listFetch_state == libssh2_NB_state_idle) {
+ if(pkey->listFetch_state == libssh2_NB_state_idle) {
pkey->listFetch_data = NULL;
pkey->listFetch_s = pkey->listFetch_buffer;
@@ -793,14 +848,15 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
pkey->listFetch_state = libssh2_NB_state_created;
}
- if (pkey->listFetch_state == libssh2_NB_state_created) {
+ if(pkey->listFetch_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0,
pkey->listFetch_buffer,
(pkey->listFetch_s -
pkey->listFetch_buffer));
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
+ }
+ else if((pkey->listFetch_s - pkey->listFetch_buffer) != rc) {
pkey->listFetch_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send publickey list packet");
@@ -809,12 +865,13 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
pkey->listFetch_state = libssh2_NB_state_sent;
}
- while (1) {
+ while(1) {
rc = publickey_packet_receive(pkey, &pkey->listFetch_data,
&pkey->listFetch_data_len);
- if (rc == LIBSSH2_ERROR_EAGAIN) {
+ if(rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ }
+ else if(rc) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for response from "
"publickey subsystem");
@@ -822,7 +879,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
}
pkey->listFetch_s = pkey->listFetch_data;
- if ((response =
+ if((response =
publickey_response_id(&pkey->listFetch_s,
pkey->listFetch_data_len)) < 0) {
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
@@ -830,31 +887,57 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
goto err_exit;
}
- switch (response) {
+ switch(response) {
case LIBSSH2_PUBLICKEY_RESPONSE_STATUS:
/* Error, or processing complete */
{
unsigned long status, descr_len, lang_len;
- status = _libssh2_ntohu32(pkey->listFetch_s);
- pkey->listFetch_s += 4;
- descr_len = _libssh2_ntohu32(pkey->listFetch_s);
- pkey->listFetch_s += 4;
- /* description starts at pkey->listFetch_s */
- pkey->listFetch_s += descr_len;
- lang_len = _libssh2_ntohu32(pkey->listFetch_s);
- pkey->listFetch_s += 4;
- /* lang starts at pkey->listFetch_s */
- pkey->listFetch_s += lang_len;
-
- if (pkey->listFetch_s >
+ if(pkey->listFetch_s + 8 <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ status = _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ descr_len = _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + descr_len + 4 <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ /* description starts at pkey->listFetch_s */
+ pkey->listFetch_s += descr_len;
+ lang_len = _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + lang_len <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ /* lang starts at pkey->listFetch_s */
+ pkey->listFetch_s += lang_len;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s >
pkey->listFetch_data + pkey->listFetch_data_len) {
_libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL,
"Malformed publickey subsystem packet");
goto err_exit;
}
- if (status == LIBSSH2_PUBLICKEY_SUCCESS) {
+ if(status == LIBSSH2_PUBLICKEY_SUCCESS) {
LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL;
*pkey_list = list;
@@ -868,7 +951,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
}
case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY:
/* What we want */
- if (keys >= max_keys) {
+ if(keys >= max_keys) {
libssh2_publickey_list *newlist;
/* Grow the key list if necessary */
max_keys += 8;
@@ -876,7 +959,7 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
LIBSSH2_REALLOC(session, list,
(max_keys +
1) * sizeof(libssh2_publickey_list));
- if (!newlist) {
+ if(!newlist) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey list");
@@ -884,17 +967,26 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
}
list = newlist;
}
- if (pkey->version == 1) {
+ if(pkey->version == 1) {
unsigned long comment_len;
- comment_len = _libssh2_ntohu32(pkey->listFetch_s);
- pkey->listFetch_s += 4;
- if (comment_len) {
+ if(pkey->listFetch_s + 4 <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ comment_len = _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(comment_len) {
list[keys].num_attrs = 1;
list[keys].attrs =
LIBSSH2_ALLOC(session,
sizeof(libssh2_publickey_attribute));
- if (!list[keys].attrs) {
+ if(!list[keys].attrs) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey attributes");
@@ -907,57 +999,184 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
list[keys].attrs[0].mandatory = 0;
pkey->listFetch_s += comment_len;
- } else {
+ }
+ 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;
- } else {
+
+ if(pkey->listFetch_s + 4 <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + list[keys].name_len <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].name = pkey->listFetch_s;
+ pkey->listFetch_s += list[keys].name_len;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + 4 <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + list[keys].blob_len <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].blob = pkey->listFetch_s;
+ pkey->listFetch_s += list[keys].blob_len;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+ }
+ 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) {
+
+ if(pkey->listFetch_s + 4 <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + list[keys].name_len <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].name = pkey->listFetch_s;
+ pkey->listFetch_s += list[keys].name_len;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + 4 <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + list[keys].blob_len <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].blob = pkey->listFetch_s;
+ pkey->listFetch_s += list[keys].blob_len;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + 4 <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].num_attrs = _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ }
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(list[keys].num_attrs) {
list[keys].attrs =
LIBSSH2_ALLOC(session,
list[keys].num_attrs *
sizeof(libssh2_publickey_attribute));
- if (!list[keys].attrs) {
+ if(!list[keys].attrs) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"publickey attributes");
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;
+ if(pkey->listFetch_s + 4 <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].attrs[i].name_len =
+ _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ }
+ else {
+ _libssh2_error(session,
+ LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + list[keys].attrs[i].name_len <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].attrs[i].name =
+ (char *) pkey->listFetch_s;
+ pkey->listFetch_s += list[keys].attrs[i].name_len;
+ }
+ else {
+ _libssh2_error(session,
+ LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s + 4 <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].attrs[i].value_len =
+ _libssh2_ntohu32(pkey->listFetch_s);
+ pkey->listFetch_s += 4;
+ }
+ else {
+ _libssh2_error(session,
+ LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
+ if(pkey->listFetch_s +
+ list[keys].attrs[i].value_len <=
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ list[keys].attrs[i].value =
+ (char *) pkey->listFetch_s;
+ pkey->listFetch_s += list[keys].attrs[i].value_len;
+ }
+ else {
+ _libssh2_error(session,
+ LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
/* actually an ignored value */
list[keys].attrs[i].mandatory = 0;
}
- } else {
+ }
+ else {
list[keys].attrs = NULL;
}
}
@@ -979,11 +1198,11 @@ libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys,
/* Only reached via explicit goto */
err_exit:
- if (pkey->listFetch_data) {
+ if(pkey->listFetch_data) {
LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL;
}
- if (list) {
+ if(list) {
libssh2_publickey_list_free(pkey, list);
}
pkey->listFetch_state = libssh2_NB_state_idle;
@@ -1005,8 +1224,8 @@ libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey,
session = pkey->channel->session;
- while (p->packet) {
- if (p->attrs) {
+ while(p->packet) {
+ if(p->attrs) {
LIBSSH2_FREE(session, p->attrs);
}
LIBSSH2_FREE(session, p->packet);
@@ -1033,25 +1252,25 @@ libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey)
/*
* Make sure all memory used in the state variables are free
*/
- if (pkey->receive_packet) {
+ if(pkey->receive_packet) {
LIBSSH2_FREE(session, pkey->receive_packet);
pkey->receive_packet = NULL;
}
- if (pkey->add_packet) {
+ if(pkey->add_packet) {
LIBSSH2_FREE(session, pkey->add_packet);
pkey->add_packet = NULL;
}
- if (pkey->remove_packet) {
+ if(pkey->remove_packet) {
LIBSSH2_FREE(session, pkey->remove_packet);
pkey->remove_packet = NULL;
}
- if (pkey->listFetch_data) {
+ if(pkey->listFetch_data) {
LIBSSH2_FREE(session, pkey->listFetch_data);
pkey->listFetch_data = NULL;
}
rc = _libssh2_channel_free(pkey->channel);
- if (rc == LIBSSH2_ERROR_EAGAIN)
+ if(rc == LIBSSH2_ERROR_EAGAIN)
return rc;
LIBSSH2_FREE(session, pkey);