diff options
| author | speidy <speidy@gmail.com> | 2017-03-19 10:20:22 +0200 | 
|---|---|---|
| committer | jsorg71 <jay.sorg@gmail.com> | 2017-03-21 22:02:29 -0700 | 
| commit | b905967ba6c3eae9803daba4b1574c050981c914 (patch) | |
| tree | 55f8bc5590c8e9ab64a238ee07d3ff4e9e7714e2 /libxrdp/xrdp_sec.c | |
| parent | 95506a169f19f954e2bdecf67896695976bbaf5a (diff) | |
| download | xrdp-proprietary-b905967ba6c3eae9803daba4b1574c050981c914.tar.gz xrdp-proprietary-b905967ba6c3eae9803daba4b1574c050981c914.zip | |
libxrdp: improve unicode_in
Diffstat (limited to 'libxrdp/xrdp_sec.c')
| -rw-r--r-- | libxrdp/xrdp_sec.c | 60 | 
1 files changed, 35 insertions, 25 deletions
| diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 1cb038e9..45d1562f 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -615,38 +615,48 @@ xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len)      self->encrypt_use_count++;  } -/*****************************************************************************/ +/***************************************************************************** + * convert utf-16 encoded string from stream into utf-8 string. + * note: uni_len doesn't include the null-terminator char. + */  static int -unicode_in(struct stream *s, int uni_len, char *dst, int dst_len) +unicode_utf16_in(struct stream *s, int uni_len, char *dst, int dst_len)  { -    int dst_index; -    int src_index; - -    dst_index = 0; -    src_index = 0; +    twchar *src; +    int num_chars; +    int i; +    int size; -    while (src_index < uni_len) +    LLOGLN(10, ("unicode_utf16_in: uni_len %d, dst_len %d", uni_len, dst_len)); +    if (uni_len == 0)      { -        if (dst_index >= dst_len || src_index > 512) +        if (!s_check_rem(s, 2))          { -            break; +            return 1;          } +        in_uint8s(s, 2); /* null terminator */ +        return 0; +    } +    size = uni_len + 2; /* include the null terminator */ +    src = g_new0(twchar, size); +    for (i = 0; i < size / 2; ++i) +    {          if (!s_check_rem(s, 2))          { +            g_free(src);              return 1;          } -        in_uint8(s, dst[dst_index]); -        in_uint8s(s, 1); -        dst_index++; -        src_index += 2; +        in_uint16_le(s, src[i]);      } - -    if (!s_check_rem(s, 2)) +    num_chars = g_wcstombs(dst, src, dst_len); +    if (num_chars < 0)      { -        return 1; +        g_memset(dst, '\0', dst_len);      } -    in_uint8s(s, 2); +    LLOGLN(10, ("unicode_utf16_in: num_chars %d, dst %s", num_chars, dst)); +    g_free(src); +      return 0;  } @@ -782,12 +792,12 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)          return 1;      } -    if (unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255) != 0) +    if (unicode_utf16_in(s, len_domain, self->rdp_layer->client_info.domain, sizeof(self->rdp_layer->client_info.domain) - 1) != 0)      {          return 1;      }      DEBUG(("domain %s", self->rdp_layer->client_info.domain)); -    if (unicode_in(s, len_user, self->rdp_layer->client_info.username, 255) != 0) +    if (unicode_utf16_in(s, len_user, self->rdp_layer->client_info.username, sizeof(self->rdp_layer->client_info.username) - 1) != 0)      {          return 1;      } @@ -795,7 +805,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)      if (flags & RDP_LOGON_AUTO)      { -        if (unicode_in(s, len_password, self->rdp_layer->client_info.password, 255) != 0) +        if (unicode_utf16_in(s, len_password, self->rdp_layer->client_info.password, sizeof(self->rdp_layer->client_info.password) - 1) != 0)          {              return 1;          } @@ -815,12 +825,12 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)          }      } -    if (unicode_in(s, len_program, self->rdp_layer->client_info.program, 255) != 0) +    if (unicode_utf16_in(s, len_program, self->rdp_layer->client_info.program, sizeof(self->rdp_layer->client_info.program) - 1) != 0)      {          return 1;      }      DEBUG(("program %s", self->rdp_layer->client_info.program)); -    if (unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255) != 0) +    if (unicode_utf16_in(s, len_directory, self->rdp_layer->client_info.directory, sizeof(self->rdp_layer->client_info.directory) - 1) != 0)      {          return 1;      } @@ -834,7 +844,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)          }          in_uint8s(s, 2);                                    /* unknown */          in_uint16_le(s, len_ip); -        if (unicode_in(s, len_ip - 2, tmpdata, 255) != 0) +        if (unicode_utf16_in(s, len_ip - 2, tmpdata, sizeof(tmpdata) - 1) != 0)          {              return 1;          } @@ -843,7 +853,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)              return 1;          }          in_uint16_le(s, len_dll); -        if (unicode_in(s, len_dll - 2, tmpdata, 255) != 0) +        if (unicode_utf16_in(s, len_dll - 2, tmpdata, sizeof(tmpdata) - 1) != 0)          {              return 1;          } | 
