# HG changeset patch # User masneyb # Date 1104533723 0 # Node ID f6e2ec8faf563905f4f957987e6daab7bc3a396f # Parent 07dc89f95076e966662934cfed0a88c619772340 2004-12-31 Brian Masney * lib/sshv2.c (sshv2_read_response) - added debugging messages if compiled with -DDEBUG. Added sshv2_response_return_code() and sshv2_buffer_get_int64(). (sshv2_buffer_get_int32) - added check_response argument to this function. This suppresses a signed/unsigned mismatch warning from gcc. (sshv2_decode_file_attributes) - decode all of the attributes that are returned from the server. (sshv2_get_next_file) - don't look at the long file name returned from the server. This also fixes a bug where no files were being returned to the user when the remote server was running the commercial SSH daemon diff -r 07dc89f95076 -r f6e2ec8faf56 ChangeLog --- a/ChangeLog Fri Dec 31 16:12:13 2004 +0000 +++ b/ChangeLog Fri Dec 31 22:55:23 2004 +0000 @@ -1,4 +1,15 @@ 2004-12-31 Brian Masney + * lib/sshv2.c (sshv2_read_response) - added debugging messages if + compiled with -DDEBUG. Added sshv2_response_return_code() + and sshv2_buffer_get_int64(). (sshv2_buffer_get_int32) - added + check_response argument to this function. This suppresses a + signed/unsigned mismatch warning from gcc. + (sshv2_decode_file_attributes) - decode all of the attributes that + are returned from the server. (sshv2_get_next_file) - don't look at + the long file name returned from the server. This also fixes a bug + where no files were being returned to the user when the remote server + was running the commercial SSH daemon + * lib/misc.c (gftp_info) - when displaying the OpenSSL information, display OPENSSL_VERSION_TEXT instead of OPENSSL_VERSION_NUMBER @@ -3187,7 +3198,7 @@ * cvsclean - added this script - * *.[ch] - added $Id: ChangeLog,v 1.387 2004/12/31 16:12:13 masneyb Exp $ tags + * *.[ch] - added $Id: ChangeLog,v 1.388 2004/12/31 22:55:23 masneyb Exp $ tags * debian/* - updated files from Debian maintainer diff -r 07dc89f95076 -r f6e2ec8faf56 lib/sshv2.c --- a/lib/sshv2.c Fri Dec 31 16:12:13 2004 +0000 +++ b/lib/sshv2.c Fri Dec 31 22:55:23 2004 +0000 @@ -771,6 +771,13 @@ pos += numread; } +#ifdef DEBUG + printf ("\rReceived message: "); + for (rem=0; remlength; rem++) + printf ("%x ", message->buffer[rem] & 0xff); + printf ("\n"); +#endif + message->buffer[message->length] = '\0'; sshv2_log_command (request, gftp_logging_recv, message->command, @@ -837,8 +844,28 @@ static int +sshv2_response_return_code (gftp_request * request, sshv2_message * message, + unsigned int ret) +{ + switch (ret) + { + case SSH_FX_OK: + case SSH_FX_EOF: + case SSH_FX_NO_SUCH_FILE: + case SSH_FX_PERMISSION_DENIED: + case SSH_FX_FAILURE: + case SSH_FX_OP_UNSUPPORTED: + return (GFTP_ERETRYABLE); + default: + return (sshv2_wrong_response (request, message)); + } +} + + +static int sshv2_buffer_get_int32 (gftp_request * request, sshv2_message * message, - int expected_response, guint32 * num) + unsigned int expected_response, int check_response, + guint32 * num) { guint32 snum; @@ -849,21 +876,45 @@ snum = ntohl (snum); message->pos += 4; - if (expected_response >= 0 && snum != expected_response) - { - switch (snum) - { - case SSH_FX_OK: - case SSH_FX_EOF: - case SSH_FX_NO_SUCH_FILE: - case SSH_FX_PERMISSION_DENIED: - case SSH_FX_FAILURE: - case SSH_FX_OP_UNSUPPORTED: - return (GFTP_ERETRYABLE); - default: - return (sshv2_wrong_response (request, message)); - } - } + if (check_response && snum != expected_response) + return (sshv2_response_return_code (request, message, snum)); + + if (num != NULL) + *num = snum; + + return (0); +} + + +static int +sshv2_buffer_get_int64 (gftp_request * request, sshv2_message * message, + unsigned int expected_response, int check_response, +#if G_HAVE_GINT64 + guint64 * num) +{ + guint64 snum; +#else + guint32 * num) +{ + guint32 snum; +#endif + guint32 hinum, lonum; + int ret; + + if ((ret = sshv2_buffer_get_int32 (request, message, 0, 0, &hinum)) < 0) + return (ret); + + if ((ret = sshv2_buffer_get_int32 (request, message, 0, 0, &lonum)) < 0) + return (ret); + +#if G_HAVE_GINT64 + snum = (gint64) lonum | ((gint64) hinum >> 32); +#else + snum = lonum; +#endif + + if (check_response && snum != expected_response) + return (sshv2_response_return_code (request, message, snum)); if (num != NULL) *num = snum; @@ -873,23 +924,31 @@ static char * -sshv2_buffer_get_string (gftp_request * request, sshv2_message * message) +sshv2_buffer_get_string (gftp_request * request, sshv2_message * message, + int return_string) { + guint32 len, buflen; char *string; - guint32 len; - if (sshv2_buffer_get_int32 (request, message, -1, &len) < 0) + if (sshv2_buffer_get_int32 (request, message, 0, 0, &len) < 0) return (NULL); - if (len > SSH_MAX_STRING_SIZE || (message->end - message->pos < len)) + buflen = message->end - message->pos; + if (len > SSH_MAX_STRING_SIZE || (buflen < len)) { sshv2_wrong_response (request, message); return (NULL); } - string = g_malloc (len + 1); - memcpy (string, message->pos, len); - string[len] = '\0'; + if (return_string) + { + string = g_malloc (len + 1); + memcpy (string, message->pos, len); + string[len] = '\0'; + } + else + string = NULL; + message->pos += len; return (string); } @@ -933,10 +992,10 @@ return (ret); message.pos += 4; - if ((ret = sshv2_buffer_get_int32 (request, &message, 1, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, &message, 1, 1, NULL)) < 0) return (ret); - if ((request->directory = sshv2_buffer_get_string (request, &message)) == NULL) + if ((request->directory = sshv2_buffer_get_string (request, &message, 1)) == NULL) return (GFTP_EFATAL); sshv2_message_free (&message); @@ -1183,39 +1242,32 @@ sshv2_decode_file_attributes (gftp_request * request, sshv2_message * message, gftp_file * fle) { - guint32 attrs, hinum, num, count, i; + guint32 attrs, num, count, i; int ret; - if ((ret = sshv2_buffer_get_int32 (request, message, -1, &attrs)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, message, 0, 0, &attrs)) < 0) return (ret); if (attrs & SSH_FILEXFER_ATTR_SIZE) { - if ((ret = sshv2_buffer_get_int32 (request, message, -1, &hinum)) < 0) - return (ret); - - if ((ret = sshv2_buffer_get_int32 (request, message, -1, &num)) < 0) + if ((ret = sshv2_buffer_get_int64 (request, message, 0, 0, &fle->size)) < 0) return (ret); - -#if G_HAVE_GINT64 - fle->size = (gint64) num | ((gint64) hinum >> 32); -#else - fle->size = num; -#endif } if (attrs & SSH_FILEXFER_ATTR_UIDGID) { - if ((ret = sshv2_buffer_get_int32 (request, message, -1, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, message, 0, 0, &num)) < 0) return (ret); + fle->user = g_strdup_printf ("%d", num); - if ((ret = sshv2_buffer_get_int32 (request, message, -1, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, message, 0, 0, &num)) < 0) return (ret); + fle->group = g_strdup_printf ("%d", num); } if (attrs & SSH_FILEXFER_ATTR_PERMISSIONS) { - if ((ret = sshv2_buffer_get_int32 (request, message, -1, &num)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, message, 0, 0, &num)) < 0) return (ret); fle->st_mode = num; @@ -1223,10 +1275,10 @@ if (attrs & SSH_FILEXFER_ATTR_ACMODTIME) { - if ((ret = sshv2_buffer_get_int32 (request, message, -1, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, message, 0, 0, NULL)) < 0) return (num); - if ((ret = sshv2_buffer_get_int32 (request, message, -1, &num)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, message, 0, 0, &num)) < 0) return (ret); fle->datetime = num; @@ -1234,18 +1286,20 @@ if (attrs & SSH_FILEXFER_ATTR_EXTENDED) { - if ((ret = sshv2_buffer_get_int32 (request, message, -1, &count)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, message, 0, 0, &count)) < 0) return (ret); for (i=0; ipos + num + 4 > message->end) return (GFTP_EFATAL); message->pos += num + 4; - if ((ret = sshv2_buffer_get_int32 (request, message, -1, &num)) < 0 || + if ((ret = sshv2_buffer_get_int32 (request, message, 0, 0, + &num)) < 0 || message->pos + num + 4 > message->end) return (GFTP_EFATAL); @@ -1260,10 +1314,10 @@ static int sshv2_get_next_file (gftp_request * request, gftp_file * fle, int fd) { - guint32 len, longnamelen; int ret, retsize, iret; sshv2_params *params; - char *longname; + char *stpos; + guint32 len; g_return_val_if_fail (request != NULL, GFTP_EFATAL); g_return_val_if_fail (request->protonum == GFTP_SSHV2_NUM, GFTP_EFATAL); @@ -1315,7 +1369,7 @@ { params->message.pos = params->message.buffer + 4; if ((iret = sshv2_buffer_get_int32 (request, - ¶ms->message, -1, + ¶ms->message, 0, 0, ¶ms->count)) < 0) return (iret); } @@ -1323,37 +1377,11 @@ if (ret == SSH_FXP_NAME) { - if (sshv2_buffer_get_int32 (request, ¶ms->message, -1, &len) < 0 || - params->message.pos + len > params->message.end) - return (GFTP_EFATAL); - - params->message.pos += len; - - if (sshv2_buffer_get_int32 (request, ¶ms->message, -1, - &longnamelen) < 0 || - params->message.pos + longnamelen > params->message.end) + stpos = params->message.pos; + if ((fle->file = sshv2_buffer_get_string (request, ¶ms->message, 1)) == NULL) return (GFTP_EFATAL); - longname = params->message.pos; - longname[longnamelen] = '\0'; - - /* The commercial SSH2 puts a / and * after some entries */ - if (longname[longnamelen - 1] == '*') - longname[--longnamelen] = '\0'; - if (longname[longnamelen - 1] == '/') - longname[--longnamelen] = '\0'; - - params->message.pos += longnamelen; - - if ((ret = gftp_parse_ls (request, longname, fle, 0)) < 0) - { - request->logging_function (gftp_logging_error, request, - _("Warning: Cannot parse listing %s\n"), - longname); - - gftp_file_destroy (fle, 0); - return (ret); - } + sshv2_buffer_get_string (request, ¶ms->message, 0); if ((ret = sshv2_decode_file_attributes (request, ¶ms->message, fle)) < 0) @@ -1362,7 +1390,7 @@ return (ret); } - retsize = strlen (longname); + retsize = params->message.pos - stpos; params->count--; } else if (ret == SSH_FXP_STATUS) @@ -1406,10 +1434,10 @@ return (ret); message.pos += 4; - if ((ret = sshv2_buffer_get_int32 (request, &message, 1, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, &message, 1, 1, NULL)) < 0) return (ret); - if ((dir = sshv2_buffer_get_string (request, &message)) == NULL) + if ((dir = sshv2_buffer_get_string (request, &message, 1)) == NULL) return (GFTP_EFATAL); if (request->directory) @@ -1450,7 +1478,7 @@ return (ret); message.pos += 4; - if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, 1, NULL)) < 0) return (ret); sshv2_message_free (&message); @@ -1485,7 +1513,7 @@ return (ret); message.pos += 4; - if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, 1, NULL)) < 0) return (ret); sshv2_message_free (&message); @@ -1527,7 +1555,7 @@ return (ret); message.pos += 4; - if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, 1, NULL)) < 0) return (ret); sshv2_message_free (&message); @@ -1565,7 +1593,7 @@ return (ret); message.pos += 4; - if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, 1, NULL)) < 0) return (ret); sshv2_message_free (&message); @@ -1619,7 +1647,7 @@ return (ret); message.pos += 4; - if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, 1, NULL)) < 0) return (ret); sshv2_message_free (&message); @@ -1662,7 +1690,7 @@ return (ret); message.pos += 4; - if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, NULL)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, 1, NULL)) < 0) return (ret); sshv2_message_free (&message); @@ -1915,7 +1943,7 @@ return (ret); message.pos += 4; - if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_EOF, + if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_EOF, 1, NULL)) < 0) return (ret); @@ -1990,7 +2018,7 @@ return (sshv2_wrong_response (request, &message)); message.pos += 4; - if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, &num)) < 0) + if ((ret = sshv2_buffer_get_int32 (request, &message, SSH_FX_OK, 1, &num)) < 0) { if (num == SSH_FX_EOF) return (0);