Changed rdp_in_unistr() to make dynamic allocation of converted string

instead of using hardcoded buffer sizes and assumtion that conversion
just fits the size.



git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/rdesktop/trunk@1773 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Henrik Andersson 2013-12-06 12:43:08 +00:00
parent 6de37a4f3b
commit f0b6604347
6 changed files with 90 additions and 66 deletions

10
disk.c
View File

@ -716,7 +716,7 @@ RD_NTSTATUS
disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM out) disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)
{ {
uint32 length, file_attributes, ft_high, ft_low; uint32 length, file_attributes, ft_high, ft_low;
char newname[PATH_MAX], fullpath[PATH_MAX]; char *newname, fullpath[PATH_MAX];
struct fileinfo *pfinfo; struct fileinfo *pfinfo;
int mode; int mode;
struct stat filestat; struct stat filestat;
@ -726,6 +726,7 @@ disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM ou
pfinfo = &(g_fileinfo[handle]); pfinfo = &(g_fileinfo[handle]);
g_notify_stamp = True; g_notify_stamp = True;
newname = NULL;
switch (info_class) switch (info_class)
{ {
@ -817,7 +818,10 @@ disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM ou
if (length && (length / 2) < 256) if (length && (length / 2) < 256)
{ {
rdp_in_unistr(in, newname, sizeof(newname), length); rdp_in_unistr(in, length, &newname, &length);
if (newname == NULL)
return RD_STATUS_INVALID_PARAMETER;
convert_to_unix_filename(newname); convert_to_unix_filename(newname);
} }
else else
@ -1194,7 +1198,7 @@ disk_query_directory(RD_NTHANDLE handle, uint32 info_class, char *pattern, STREA
case FileNamesInformation: case FileNamesInformation:
/* If a search pattern is received, remember this pattern, and restart search */ /* If a search pattern is received, remember this pattern, and restart search */
if (pattern[0] != 0) if (pattern != NULL && pattern[0] != 0)
{ {
strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), PATH_MAX - 1); strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), PATH_MAX - 1);
rewinddir(pdir); rewinddir(pdir);

View File

@ -231,7 +231,9 @@ void
printercache_process(STREAM s) printercache_process(STREAM s)
{ {
uint32 type, printer_length, driver_length, printer_unicode_length, blob_length; uint32 type, printer_length, driver_length, printer_unicode_length, blob_length;
char device_name[9], printer[256], driver[256]; char device_name[9], *printer, *driver;
printer = driver = NULL;
in_uint32_le(s, type); in_uint32_le(s, type);
switch (type) switch (type)
@ -244,17 +246,22 @@ printercache_process(STREAM s)
/* NOTE - 'driver' doesn't contain driver, it contains the new printer name */ /* NOTE - 'driver' doesn't contain driver, it contains the new printer name */
rdp_in_unistr(s, printer, sizeof(printer), printer_length); rdp_in_unistr(s, printer_length, &printer, &printer_length);
rdp_in_unistr(s, driver, sizeof(driver), driver_length); rdp_in_unistr(s, driver_length, &driver, &driver_length);
printercache_rename_blob(printer, driver); printercache_rename_blob(printer, driver);
free(printer);
free(driver);
break; break;
case 3: /* delete item */ case 3: /* delete item */
in_uint8(s, printer_unicode_length); in_uint8(s, printer_unicode_length);
in_uint8s(s, 0x3); /* padding */ in_uint8s(s, 0x3); /* padding */
rdp_in_unistr(s, printer, sizeof(printer), printer_unicode_length); rdp_in_unistr(s, printer_unicode_length, &printer, &printer_unicode_length);
printercache_unlink_blob(printer); if (printer)
printercache_unlink_blob(printer);
free(printer);
break; break;
case 2: /* save printer data */ case 2: /* save printer data */
@ -263,8 +270,10 @@ printercache_process(STREAM s)
if (printer_unicode_length < 2 * 255) if (printer_unicode_length < 2 * 255)
{ {
rdp_in_unistr(s, printer, sizeof(printer), printer_unicode_length); rdp_in_unistr(s, printer_unicode_length, &printer, &printer_unicode_length);
printercache_save_blob(printer, s->p, blob_length); if (printer)
printercache_save_blob(printer, s->p, blob_length);
free(printer);
} }
break; break;

View File

@ -156,7 +156,7 @@ RD_BOOL rd_lock_file(int fd, int start, int len);
void rdp5_process(STREAM s); void rdp5_process(STREAM s);
/* rdp.c */ /* rdp.c */
void rdp_out_unistr(STREAM s, char *string, int len); void rdp_out_unistr(STREAM s, char *string, int len);
int rdp_in_unistr(STREAM s, char *string, int str_len, int in_len); void rdp_in_unistr(STREAM s, int in_len, char **string, uint32 *str_size);
void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
uint16 param2); uint16 param2);
void rdp_send_client_window_status(int status); void rdp_send_client_window_status(int status);

View File

@ -116,7 +116,8 @@ uint32 g_rdp5_performanceflags =
RD_BOOL g_redirect = False; RD_BOOL g_redirect = False;
char *g_redirect_server; char *g_redirect_server;
uint32 g_redirect_server_len; uint32 g_redirect_server_len;
char g_redirect_domain[16]; char *g_redirect_domain;
uint32 g_redirect_domain_len;
char *g_redirect_username; char *g_redirect_username;
uint32 g_redirect_username_len; uint32 g_redirect_username_len;
uint8 *g_redirect_lb_info; uint8 *g_redirect_lb_info;

83
rdp.c
View File

@ -66,8 +66,8 @@ extern RDPCOMP g_mppc_dict;
extern RD_BOOL g_redirect; extern RD_BOOL g_redirect;
extern char *g_redirect_server; extern char *g_redirect_server;
extern uint32 g_redirect_server_len; extern uint32 g_redirect_server_len;
extern char g_redirect_domain[16]; extern char *g_redirect_domain;
extern char g_redirect_password[64]; extern uint32 g_redirect_domain_len;
extern char *g_redirect_username; extern char *g_redirect_username;
extern uint32 g_redirect_username_len; extern uint32 g_redirect_username_len;
extern uint8 *g_redirect_lb_info; extern uint8 *g_redirect_lb_info;
@ -259,12 +259,16 @@ rdp_out_unistr(STREAM s, char *string, int len)
* *
* Returns str_len of string * Returns str_len of string
*/ */
int void
rdp_in_unistr(STREAM s, char *string, int str_size, int in_len) rdp_in_unistr(STREAM s, int in_len, char **string, uint32 *str_size)
{ {
/* Dynamic allocate of destination string if not provided */
*string = xmalloc(in_len * 2);
*str_size = in_len * 2;
#ifdef HAVE_ICONV #ifdef HAVE_ICONV
size_t ibl = in_len, obl = str_size - 1; size_t ibl = in_len, obl = *str_size - 1;
char *pin = (char *) s->p, *pout = string; char *pin = (char *) s->p, *pout = *string;
static iconv_t iconv_h = (iconv_t) - 1; static iconv_t iconv_h = (iconv_t) - 1;
if (g_iconv_works) if (g_iconv_works)
@ -277,7 +281,7 @@ rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
WINDOWS_CODEPAGE, g_codepage, iconv_h); WINDOWS_CODEPAGE, g_codepage, iconv_h);
g_iconv_works = False; g_iconv_works = False;
return rdp_in_unistr(s, string, str_size, in_len); return rdp_in_unistr(s, in_len, string, str_size);
} }
} }
@ -289,12 +293,11 @@ rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
} }
else else
{ {
iconv_close(iconv_h);
iconv_h = (iconv_t) - 1;
warning("rdp_in_unistr: iconv fail, errno %d\n", errno); warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
g_iconv_works = False; free(*string);
return rdp_in_unistr(s, string, str_size, in_len); *string = NULL;
*str_size = 0;
} }
} }
@ -302,19 +305,21 @@ rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
s->p += in_len; s->p += in_len;
*pout = 0; *pout = 0;
return pout - string;
if (*string)
*str_size = pout - *string;
} }
else else
#endif #endif
{ {
int i = 0; int i = 0;
int len = in_len / 2;
int rem = 0; int rem = 0;
uint32 len = in_len / 2;
if (len > str_size - 1) if (len > *str_size - 1)
{ {
warning("server sent an unexpectedly long string, truncating\n"); warning("server sent an unexpectedly long string, truncating\n");
len = str_size - 1; len = *str_size - 1;
rem = in_len - 2 * len; rem = in_len - 2 * len;
} }
@ -326,7 +331,7 @@ rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
in_uint8s(s, rem); in_uint8s(s, rem);
string[len] = 0; string[len] = 0;
return len; *str_size = len;
} }
} }
@ -1515,7 +1520,19 @@ process_redirect_pdu(STREAM s, RD_BOOL enhanced_redirect /*, uint32 * ext_disc_r
uint32 len; uint32 len;
uint16 redirect_identifier; uint16 redirect_identifier;
/* reset any previous redirection information */
g_redirect = True; g_redirect = True;
free(g_redirect_server);
free(g_redirect_username);
free(g_redirect_domain);
free(g_redirect_lb_info);
free(g_redirect_cookie);
g_redirect_server = NULL;
g_redirect_username = NULL;
g_redirect_domain = NULL;
g_redirect_lb_info = NULL;
g_redirect_cookie = NULL;
/* these 2 bytes are unknown, seem to be zeros */ /* these 2 bytes are unknown, seem to be zeros */
in_uint8s(s, 2); in_uint8s(s, 2);
@ -1545,14 +1562,10 @@ process_redirect_pdu(STREAM s, RD_BOOL enhanced_redirect /*, uint32 * ext_disc_r
if (g_redirect_flags & PDU_REDIRECT_HAS_IP) if (g_redirect_flags & PDU_REDIRECT_HAS_IP)
{ {
/* read length of ip string */ /* read length of ip string */
in_uint32_le(s, g_redirect_server_len); in_uint32_le(s, len);
if (g_redirect_server)
free(g_redirect_server);
g_redirect_server = xmalloc(g_redirect_server_len);
/* read ip string */ /* read ip string */
rdp_in_unistr(s, g_redirect_server, g_redirect_server_len, g_redirect_server_len); rdp_in_unistr(s, len, &g_redirect_server, &g_redirect_server_len);
} }
if (g_redirect_flags & PDU_REDIRECT_HAS_LOAD_BALANCE_INFO) if (g_redirect_flags & PDU_REDIRECT_HAS_LOAD_BALANCE_INFO)
@ -1573,16 +1586,10 @@ process_redirect_pdu(STREAM s, RD_BOOL enhanced_redirect /*, uint32 * ext_disc_r
if (g_redirect_flags & PDU_REDIRECT_HAS_USERNAME) if (g_redirect_flags & PDU_REDIRECT_HAS_USERNAME)
{ {
/* read length of username string */ /* read length of username string */
in_uint32_le(s, g_redirect_username_len); in_uint32_le(s, len);
/* reallocate a loadbalance info blob */
if (g_redirect_username != NULL)
free(g_redirect_username);
g_redirect_username = xmalloc(g_redirect_username_len);
/* read username string */ /* read username string */
rdp_in_unistr(s, g_redirect_username, g_redirect_username_len, g_redirect_username_len); rdp_in_unistr(s, len, &g_redirect_username, &g_redirect_username_len);
} }
if (g_redirect_flags & PDU_REDIRECT_HAS_DOMAIN) if (g_redirect_flags & PDU_REDIRECT_HAS_DOMAIN)
@ -1591,7 +1598,7 @@ process_redirect_pdu(STREAM s, RD_BOOL enhanced_redirect /*, uint32 * ext_disc_r
in_uint32_le(s, len); in_uint32_le(s, len);
/* read domain string */ /* read domain string */
rdp_in_unistr(s, g_redirect_domain, sizeof(g_redirect_domain), len); rdp_in_unistr(s, len, &g_redirect_domain, &g_redirect_domain_len);
} }
if (g_redirect_flags & PDU_REDIRECT_HAS_PASSWORD) if (g_redirect_flags & PDU_REDIRECT_HAS_PASSWORD)
@ -1631,15 +1638,17 @@ process_redirect_pdu(STREAM s, RD_BOOL enhanced_redirect /*, uint32 * ext_disc_r
if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_FQDN) if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_FQDN)
{ {
/* read length of fqdn string */ in_uint32_le(s, len);
in_uint32_le(s, g_redirect_server_len);
if (g_redirect_server)
free(g_redirect_server);
g_redirect_server = xmalloc(g_redirect_server_len); /* Let target fqdn replace target ip address */
if (g_redirect_server)
{
free(g_redirect_server);
g_redirect_server = NULL;
}
/* read fqdn string */ /* read fqdn string */
rdp_in_unistr(s, g_redirect_server, g_redirect_server_len, g_redirect_server_len); rdp_in_unistr(s, len, &g_redirect_server, &g_redirect_server_len);
} }
if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_NETBIOS) if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_NETBIOS)

29
rdpdr.c
View File

@ -362,7 +362,9 @@ rdpdr_process_irp(STREAM s)
error_mode, error_mode,
share_mode, disposition, total_timeout, interval_timeout, flags_and_attributes = 0; share_mode, disposition, total_timeout, interval_timeout, flags_and_attributes = 0;
char filename[PATH_MAX]; char *filename;
uint32 filename_len;
uint8 *buffer, *pst_buf; uint8 *buffer, *pst_buf;
struct stream out; struct stream out;
DEVICE_FNS *fns; DEVICE_FNS *fns;
@ -439,22 +441,22 @@ rdpdr_process_irp(STREAM s)
if (length && (length / 2) < 256) if (length && (length / 2) < 256)
{ {
rdp_in_unistr(s, filename, sizeof(filename), length); rdp_in_unistr(s, length, &filename, &filename_len);
convert_to_unix_filename(filename); if (filename)
} convert_to_unix_filename(filename);
else
{
filename[0] = 0;
} }
if (!fns->create) if (!fns->create)
{ {
status = RD_STATUS_NOT_SUPPORTED; status = RD_STATUS_NOT_SUPPORTED;
free(filename);
break; break;
} }
status = fns->create(device, desired_access, share_mode, disposition, status = fns->create(device, desired_access, share_mode, disposition,
flags_and_attributes, filename, &result); flags_and_attributes, filename, &result);
free(filename);
buffer_len = 1; buffer_len = 1;
break; break;
@ -632,14 +634,11 @@ rdpdr_process_irp(STREAM s)
in_uint8s(s, 0x17); in_uint8s(s, 0x17);
if (length && length < 2 * 255) if (length && length < 2 * 255)
{ {
rdp_in_unistr(s, filename, sizeof(filename), rdp_in_unistr(s, length, &filename, &filename_len);
length); if (filename)
convert_to_unix_filename(filename); convert_to_unix_filename(filename);
}
else
{
filename[0] = 0;
} }
out.data = out.p = buffer; out.data = out.p = buffer;
out.size = sizeof(buffer); out.size = sizeof(buffer);
status = disk_query_directory(file, info_level, filename, status = disk_query_directory(file, info_level, filename,
@ -647,6 +646,8 @@ rdpdr_process_irp(STREAM s)
result = buffer_len = out.p - out.data; result = buffer_len = out.p - out.data;
if (!buffer_len) if (!buffer_len)
buffer_len++; buffer_len++;
free(filename);
break; break;
case IRP_MN_NOTIFY_CHANGE_DIRECTORY: case IRP_MN_NOTIFY_CHANGE_DIRECTORY: