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:
parent
6de37a4f3b
commit
f0b6604347
10
disk.c
10
disk.c
@ -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);
|
||||||
|
@ -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);
|
||||||
|
if (printer)
|
||||||
printercache_unlink_blob(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);
|
||||||
|
if (printer)
|
||||||
printercache_save_blob(printer, s->p, blob_length);
|
printercache_save_blob(printer, s->p, blob_length);
|
||||||
|
free(printer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
2
proto.h
2
proto.h
@ -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);
|
||||||
|
@ -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
83
rdp.c
@ -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)
|
||||||
|
25
rdpdr.c
25
rdpdr.c
@ -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);
|
||||||
|
if (filename)
|
||||||
convert_to_unix_filename(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:
|
||||||
|
Loading…
Reference in New Issue
Block a user