http://rdesktop.cvs.sourceforge.net/rdesktop/rdesktop/rdp.c?r1=1.101&r2=1.102&view=patch&pathrev=HEAD --- rdp.c 2007/12/23 07:07:50 1.101 +++ rdp.c 2008/01/05 05:43:02 1.102 @@ -243,10 +243,10 @@ * Returns str_len of string */ int -rdp_in_unistr(STREAM s, char *string, int uni_len) +rdp_in_unistr(STREAM s, char *string, int str_size, int in_len) { #ifdef HAVE_ICONV - size_t ibl = uni_len, obl = uni_len; + size_t ibl = in_len, obl = str_size-1; char *pin = (char *) s->p, *pout = string; static iconv_t iconv_h = (iconv_t) - 1; @@ -260,37 +260,56 @@ WINDOWS_CODEPAGE, g_codepage, iconv_h); g_iconv_works = False; - return rdp_in_unistr(s, string, uni_len); + return rdp_in_unistr(s, string, str_size, in_len); } } if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) { - iconv_close(iconv_h); - iconv_h = (iconv_t) - 1; - warning("rdp_in_unistr: iconv fail, errno %d\n", errno); + if (errno == E2BIG) + { + warning("server sent an unexpectedly long string, truncating\n"); + } + else + { + iconv_close(iconv_h); + iconv_h = (iconv_t) - 1; + warning("rdp_in_unistr: iconv fail, errno %d\n", errno); - g_iconv_works = False; - return rdp_in_unistr(s, string, uni_len); + g_iconv_works = False; + return rdp_in_unistr(s, string, str_size, in_len); + } } /* we must update the location of the current STREAM for future reads of s->p */ - s->p += uni_len; + s->p += in_len; + *pout = 0; return pout - string; } else #endif { int i = 0; + int len = in_len/2; + int rem = 0; + + if (len > str_size-1) + { + warning("server sent an unexpectedly long string, truncating\n"); + len = str_size-1; + rem = in_len - 2*len; + } - while (i < uni_len / 2) + while (i < len) { in_uint8a(s, &string[i++], 1); in_uint8s(s, 1); } - return i - 1; + in_uint8s(s, rem); + string[len] = 0; + return len; } } @@ -1325,32 +1344,44 @@ in_uint32_le(s, len); /* read ip string */ - rdp_in_unistr(s, g_redirect_server, len); + rdp_in_unistr(s, g_redirect_server, sizeof(g_redirect_server), len); /* read length of cookie string */ in_uint32_le(s, len); /* read cookie string (plain ASCII) */ - in_uint8a(s, g_redirect_cookie, len); + if (len > sizeof(g_redirect_cookie)-1) + { + uint32 rem = len - (sizeof(g_redirect_cookie)-1); + len = sizeof(g_redirect_cookie)-1; + + warning("Unexpectedly large redirection cookie\n"); + in_uint8a(s, g_redirect_cookie, len); + in_uint8s(s, rem); + } + else + { + in_uint8a(s, g_redirect_cookie, len); + } g_redirect_cookie[len] = 0; /* read length of username string */ in_uint32_le(s, len); /* read username string */ - rdp_in_unistr(s, g_redirect_username, len); + rdp_in_unistr(s, g_redirect_username, sizeof(g_redirect_username), len); /* read length of domain string */ in_uint32_le(s, len); /* read domain string */ - rdp_in_unistr(s, g_redirect_domain, len); + rdp_in_unistr(s, g_redirect_domain, sizeof(g_redirect_domain), len); /* read length of password string */ in_uint32_le(s, len); /* read password string */ - rdp_in_unistr(s, g_redirect_password, len); + rdp_in_unistr(s, g_redirect_password, sizeof(g_redirect_password), len); g_redirect = True;