OpenVAS Scanner 23.32.3
charcnv.c File Reference

Unix SMB/CIFS implementation: Character set conversion Extensions. More...

#include "byteorder.h"
#include "iconv.h"
#include "proto.h"
#include "smb.h"
#include <gvm/base/logging.h>
Include dependency graph for charcnv.c:

Go to the source code of this file.

Macros

#define uint8   uint8_t
#define uint16   uint16_t
#define _PUBLIC_
#define G_LOG_DOMAIN   "lib nasl"
 GLib logging domain.
#define False   0
#define True   1

Typedefs

typedef unsigned int bool

Functions

size_t convert_string_ntlmssp (charset_t from, charset_t to, void const *src, size_t srclen, void *dest, size_t destlen, bool allow_badcharcnv)
static int check_dos_char_slowly_ntlmssp (uint16 c)
static char lp_failed_convert_char_ntlmssp (void)
static void init_valid_table_ntlmssp (void)
static size_t strlen_w_ntlmssp (const uint16 *src)
static const char * charset_name_ntlmssp (charset_t ch)
void lazy_initialize_conv_ntlmssp (void)
void init_iconv_ntlmssp (void)
static size_t convert_string_internal_ntlmssp (charset_t from, charset_t to, void const *src, size_t srclen, void *dest, size_t destlen, bool allow_bad_conv)

Variables

static uint8valid_table_ntlmssp
static bool valid_table_use_unmap_ntlmssp
static smb_iconv_t conv_handles_ntlmssp [NUM_CHARSETS][NUM_CHARSETS]
static bool conv_silent_ntlmssp

Detailed Description

Unix SMB/CIFS implementation: Character set conversion Extensions.

Character-set conversion routines built on our iconv.

MODIFICATIONS: only those functions that are required for OpenVAS are retained, others are removed Modified By Preeti Subramanian spree.nosp@m.ti@s.nosp@m.ecpod.nosp@m..com

  1. init_valid_table taken from samba/<source>/lib/util_unistr.c, using a dynamically created valid table only
  2. valid_table taken from samba/<source>/lib/util_unistr.c
  3. valid_table_use_unmap taken from samba/<source>/lib/util_unistr.c, BOOL is changed to bool
  4. check_dos_char_slowly taken from samba/<source>/lib/util_unistr.c, smb_ucs2_t is changed to uint16
  5. strlen_w taken from samba/<source>/lib/util_unistr.c, smb_ucs2_t is changed to uint16
  6. strupper_m taken from samba/source/lib/util_str.c, and modified for OpenVAS
  7. charset_name function changed for OpenVAS
  8. in lazy_initialize_conv function, loading or generating the case handling tables removed
  9. in init_iconv, init_doschar_table not required(removed)
Note
Samba's internal character set (at least in the 3.0 series) is always the same as the one for the Unix filesystem. It is not necessarily UTF-8 and may be different on machines that need i18n filenames to be compatible with Unix software. It does have to be a superset of ASCII. All multibyte sequences must start with a byte with the high bit set.
See also
lib/iconv.c

Definition in file charcnv.c.

Macro Definition Documentation

◆ _PUBLIC_

#define _PUBLIC_

Definition at line 53 of file charcnv.c.

◆ False

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "lib nasl"

GLib logging domain.

Definition at line 60 of file charcnv.c.

◆ True

#define True   1

◆ uint16

#define uint16   uint16_t

◆ uint8

Typedef Documentation

◆ bool

typedef unsigned int bool

Definition at line 62 of file charcnv.c.

Function Documentation

◆ charset_name_ntlmssp()

const char * charset_name_ntlmssp ( charset_t ch)
static
  • Return the name of a charset to give to iconv().

Definition at line 182 of file charcnv.c.

183{
184 const char *ret = NULL;
185
186 if (ch == CH_UTF16LE)
187 ret = "UTF-16LE";
188 else if (ch == CH_UTF16BE)
189 ret = "UTF-16BE";
190 else if (ch == CH_UTF8)
191 ret = "UTF8";
192
193#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
194 if (ret && !strcmp (ret, "LOCALE"))
195 {
196 const char *ln = NULL;
197
198#ifdef HAVE_SETLOCALE
199 setlocale (LC_ALL, "");
200#endif
201 ln = nl_langinfo (CODESET);
202 if (ln)
203 {
204 /* Check whether the charset name is supported
205 by iconv */
206 smb_iconv_t handle = smb_iconv_open_ntlmssp (ln, "UCS-2LE");
207 if (handle == (smb_iconv_t) -1)
208 {
209 ln = NULL;
210 }
211 else
212 {
214 }
215 }
216 ret = ln;
217 }
218#endif
219
220 if (!ret || !*ret)
221 ret = "ASCII";
222 return ret;
223}
@ CH_UTF16BE
Definition charset.h:31
@ CH_UTF16LE
Definition charset.h:25
@ CH_UTF8
Definition charset.h:30
int smb_iconv_close_ntlmssp(smb_iconv_t cd)
Definition iconv.c:203
smb_iconv_t smb_iconv_open_ntlmssp(const char *tocode, const char *fromcode)
Definition iconv.c:101
struct _smb_iconv_t * smb_iconv_t

References CH_UTF16BE, CH_UTF16LE, CH_UTF8, smb_iconv_close_ntlmssp(), and smb_iconv_open_ntlmssp().

Referenced by init_iconv_ntlmssp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_dos_char_slowly_ntlmssp()

int check_dos_char_slowly_ntlmssp ( uint16 c)
static

Definition at line 73 of file charcnv.c.

74{
75 char buf[10];
76 uint16_t c2 = 0;
77 size_t len1, len2;
78
79 len1 = convert_string_ntlmssp (CH_UTF16LE, CH_DOS, &c, 2, buf, sizeof (buf),
80 False);
81
82 /* convert_string_ntlmssp returns a size_t value, and uses
83 * (size_t) -1 as error code */
84 if (len1 == 0 || len1 == (size_t) -1)
85 {
86 return 0;
87 }
88 len2 = convert_string_ntlmssp (CH_DOS, CH_UTF16LE, buf, len1, &c2, 2, False);
89 if (len2 != 2)
90 {
91 return 0;
92 }
93 return (c == c2);
94}
#define False
Definition charcnv.c:63
size_t convert_string_ntlmssp(charset_t from, charset_t to, void const *src, size_t srclen, void *dest, size_t destlen, bool allow_badcharcnv)
Definition charcnv.c:493
@ CH_DOS
Definition charset.h:29

References CH_DOS, CH_UTF16LE, convert_string_ntlmssp(), False, and uint16.

Referenced by init_valid_table_ntlmssp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ convert_string_internal_ntlmssp()

size_t convert_string_internal_ntlmssp ( charset_t from,
charset_t to,
void const * src,
size_t srclen,
void * dest,
size_t destlen,
bool allow_bad_conv )
static

Convert string from one encoding to another, making error checking etc Slow path version - uses (slow) iconv.

Parameters
srcpointer to source string (multibyte or singlebyte)
srclenlength of the source string in bytes
destpointer to destination string (multibyte or singlebyte)
destlenmaximal length allowed for string
allow_bad_convdetermines if a "best effort" conversion is acceptable (never returns errors)
Returns
the number of bytes occupied in the destination

Ensure the srclen contains the terminating zero.

Definition at line 325 of file charcnv.c.

328{
329 size_t i_len, o_len;
330 size_t retval;
331 const char *inbuf = (const char *) src;
332 char *outbuf = (char *) dest;
333 smb_iconv_t descriptor;
334
336
337 descriptor = conv_handles_ntlmssp[from][to];
338
339 if (srclen == (size_t) -1)
340 {
341 if (from == CH_UTF16LE || from == CH_UTF16BE)
342 {
343 srclen = (strlen_w_ntlmssp ((const uint16 *) src) + 1) * 2;
344 }
345 else
346 {
347 srclen = strlen ((const char *) src) + 1;
348 }
349 }
350
351 if (descriptor == (smb_iconv_t) -1 || descriptor == (smb_iconv_t) 0)
352 return (size_t) -1;
353
354 i_len = srclen;
355 o_len = destlen;
356
357again:
358
359 retval = smb_iconv_ntlmssp (descriptor, &inbuf, &i_len, &outbuf, &o_len);
360 if (retval == (size_t) -1)
361 {
362 switch (errno)
363 {
364 case EINVAL:
365 /* Incomplete multibyte sequence */
367 if (allow_bad_conv)
368 goto use_as_is;
369 return (size_t) -1;
370 case E2BIG:
371 /* No more room */
372 break;
373 case EILSEQ:
374 /* Illegal multibyte sequence */
375 if (allow_bad_conv)
376 goto use_as_is;
377
378 return (size_t) -1;
379 default:
380 /* unknown error */
381 return (size_t) -1;
382 }
383 }
384 return destlen - o_len;
385
386use_as_is:
387
388 /*
389 * Conversion not supported. This is actually an error, but there are so
390 * many misconfigured iconv systems and smb.conf's out there we can't just
391 * fail. Do a very bad conversion instead.... JRA.
392 */
393
394 {
395 if (o_len == 0 || i_len == 0)
396 return destlen - o_len;
397
398 if (((from == CH_UTF16LE) || (from == CH_UTF16BE))
399 && ((to != CH_UTF16LE) && (to != CH_UTF16BE)))
400 {
401 /* Can't convert from utf16 any endian to multibyte.
402 Replace with the default fail char.
403 */
404 if (i_len < 2)
405 return destlen - o_len;
406 if (i_len >= 2)
407 {
409
410 outbuf++;
411 o_len--;
412
413 inbuf += 2;
414 i_len -= 2;
415 }
416
417 if (o_len == 0 || i_len == 0)
418 return destlen - o_len;
419
420 /* Keep trying with the next char... */
421 goto again;
422 }
423 else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE)
424 {
425 /* Can't convert to UTF16LE - just widen by adding the
426 default fail char then zero.
427 */
428 if (o_len < 2)
429 return destlen - o_len;
430
431 outbuf[0] = lp_failed_convert_char_ntlmssp ();
432 outbuf[1] = '\0';
433
434 inbuf++;
435 i_len--;
436
437 outbuf += 2;
438 o_len -= 2;
439
440 if (o_len == 0 || i_len == 0)
441 return destlen - o_len;
442
443 /* Keep trying with the next char... */
444 goto again;
445 }
446 else if (from != CH_UTF16LE && from != CH_UTF16BE && to != CH_UTF16LE
447 && to != CH_UTF16BE)
448 {
449 /* Failed multibyte to multibyte. Just copy the default fail char and
450 try again. */
451 outbuf[0] = lp_failed_convert_char_ntlmssp ();
452
453 inbuf++;
454 i_len--;
455
456 outbuf++;
457 o_len--;
458
459 if (o_len == 0 || i_len == 0)
460 return destlen - o_len;
461
462 /* Keep trying with the next char... */
463 goto again;
464 }
465 else
466 {
467 /* Keep compiler happy.... */
468 return destlen - o_len;
469 }
470 }
471}
static smb_iconv_t conv_handles_ntlmssp[NUM_CHARSETS][NUM_CHARSETS]
Definition charcnv.c:119
static size_t strlen_w_ntlmssp(const uint16 *src)
Definition charcnv.c:165
static bool conv_silent_ntlmssp
Definition charcnv.c:121
void lazy_initialize_conv_ntlmssp(void)
Definition charcnv.c:226
static char lp_failed_convert_char_ntlmssp(void)
Definition charcnv.c:99
#define uint16
Definition charcnv.c:49
size_t smb_iconv_ntlmssp(smb_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition iconv.c:53
#define EILSEQ
Definition iconv.h:40

References CH_UTF16BE, CH_UTF16LE, conv_handles_ntlmssp, conv_silent_ntlmssp, EILSEQ, lazy_initialize_conv_ntlmssp(), lp_failed_convert_char_ntlmssp(), smb_iconv_ntlmssp(), strlen_w_ntlmssp(), and uint16.

Referenced by convert_string_ntlmssp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ convert_string_ntlmssp()

size_t convert_string_ntlmssp ( charset_t from,
charset_t to,
void const * src,
size_t srclen,
void * dest,
size_t destlen,
bool allow_bad_conv )

Convert string from one encoding to another, making error checking etc Fast path version - handles ASCII first.

Parameters
srcpointer to source string (multibyte or singlebyte)
srclenlength of the source string in bytes, or -1 for nul terminated.
destpointer to destination string (multibyte or singlebyte)
destlenmaximal length allowed for string - NEVER -1.
allow_bad_convdetermines if a "best effort" conversion is acceptable (never returns errors)
Returns
the number of bytes occupied in the destination. On error (size_t) -1 as error code.

Ensure the srclen contains the terminating zero.

This function has been hand-tuned to provide a fast path. Don't change unless you really know what you are doing. JRA.

Definition at line 493 of file charcnv.c.

496{
497 /*
498 * NB. We deliberately don't do a strlen here if srclen == -1.
499 * This is very expensive over millions of calls and is taken
500 * care of in the slow path in convert_string_internal. JRA.
501 */
502
503 if (srclen == 0)
504 return 0;
505
506 if (from != CH_UTF16LE && from != CH_UTF16BE && to != CH_UTF16LE
507 && to != CH_UTF16BE)
508 {
509 const unsigned char *p = (const unsigned char *) src;
510 unsigned char *q = (unsigned char *) dest;
511 size_t slen = srclen;
512 size_t dlen = destlen;
513 unsigned char lastp = '\0';
514 size_t retval = 0;
515
516 /* If all characters are ascii, fast path here. */
517 while (slen && dlen)
518 {
519 if ((lastp = *p) <= 0x7f)
520 {
521 *q++ = *p++;
522 if (slen != (size_t) -1)
523 {
524 slen--;
525 }
526 dlen--;
527 retval++;
528 if (!lastp)
529 break;
530 }
531 else
532 {
533#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
534 goto general_case;
535#else
537 from, to, p, slen, q, dlen, allow_bad_conv);
538 if (ret == (size_t) -1)
539 {
540 return ret;
541 }
542 return retval + ret;
543#endif
544 }
545 }
546 if (!dlen)
547 {
548 /* Even if we fast path we should note if we ran out of room. */
549 if (((slen != (size_t) -1) && slen)
550 || ((slen == (size_t) -1) && lastp))
551 {
552 errno = E2BIG;
553 }
554 }
555 return retval;
556 }
557 else if (from == CH_UTF16LE && to != CH_UTF16LE)
558 {
559 const unsigned char *p = (const unsigned char *) src;
560 unsigned char *q = (unsigned char *) dest;
561 size_t retval = 0;
562 size_t slen = srclen;
563 size_t dlen = destlen;
564 unsigned char lastp = '\0';
565
566 /* If all characters are ascii, fast path here. */
567 while (((slen == (size_t) -1) || (slen >= 2)) && dlen)
568 {
569 if (((lastp = *p) <= 0x7f) && (p[1] == 0))
570 {
571 *q++ = *p;
572 if (slen != (size_t) -1)
573 {
574 slen -= 2;
575 }
576 p += 2;
577 dlen--;
578 retval++;
579 if (!lastp)
580 break;
581 }
582 else
583 {
584#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
585 goto general_case;
586#else
587 return retval
588 + convert_string_internal_ntlmssp (from, to, p, slen, q,
589 dlen, allow_bad_conv);
590#endif
591 }
592 }
593 if (!dlen)
594 {
595 /* Even if we fast path we should note if we ran out of room. */
596 if (((slen != (size_t) -1) && slen)
597 || ((slen == (size_t) -1) && lastp))
598 {
599 errno = E2BIG;
600 }
601 }
602 return retval;
603 }
604 else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE)
605 {
606 const unsigned char *p = (const unsigned char *) src;
607 unsigned char *q = (unsigned char *) dest;
608 size_t retval = 0;
609 size_t slen = srclen;
610 size_t dlen = destlen;
611 unsigned char lastp = '\0';
612
613 /* If all characters are ascii, fast path here. */
614 while (slen && (dlen >= 2))
615 {
616 if ((lastp = *p) <= 0x7F)
617 {
618 *q++ = *p++;
619 *q++ = '\0';
620 if (slen != (size_t) -1)
621 {
622 slen--;
623 }
624 dlen -= 2;
625 retval += 2;
626 if (!lastp)
627 break;
628 }
629 else
630 {
631#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
632 goto general_case;
633#else
634 return retval
635 + convert_string_internal_ntlmssp (from, to, p, slen, q,
636 dlen, allow_bad_conv);
637#endif
638 }
639 }
640 if (!dlen)
641 {
642 /* Even if we fast path we should note if we ran out of room. */
643 if (((slen != (size_t) -1) && slen)
644 || ((slen == (size_t) -1) && lastp))
645 {
646 errno = E2BIG;
647 }
648 }
649 return retval;
650 }
651
652#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
653general_case:
654#endif
655 return convert_string_internal_ntlmssp (from, to, src, srclen, dest, destlen,
656 allow_bad_conv);
657}
static size_t convert_string_internal_ntlmssp(charset_t from, charset_t to, void const *src, size_t srclen, void *dest, size_t destlen, bool allow_bad_conv)
Definition charcnv.c:325

References CH_UTF16BE, CH_UTF16LE, and convert_string_internal_ntlmssp().

Referenced by check_dos_char_slowly_ntlmssp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_iconv_ntlmssp()

void init_iconv_ntlmssp ( void )

Initialize iconv conversion descriptors.

This is called the first time it is needed, and also called again every time the configuration is reloaded, because the charset or codepage might have changed.

Definition at line 245 of file charcnv.c.

246{
247 int c1, c2;
248 bool did_reload = False;
249
250 /* so that charset_name() works we need to get the UNIX<->UCS2 going
251 first */
255
259
260 for (c1 = 0; c1 < NUM_CHARSETS; c1++)
261 {
262 for (c2 = 0; c2 < NUM_CHARSETS; c2++)
263 {
264 const char *n1 = charset_name_ntlmssp ((charset_t) c1);
265 const char *n2 = charset_name_ntlmssp ((charset_t) c2);
266 if (conv_handles_ntlmssp[c1][c2]
267 && strcmp (n1, conv_handles_ntlmssp[c1][c2]->from_name) == 0
268 && strcmp (n2, conv_handles_ntlmssp[c1][c2]->to_name) == 0)
269 continue;
270
271 did_reload = True;
272
273 if (conv_handles_ntlmssp[c1][c2])
275
277 if (conv_handles_ntlmssp[c1][c2] == (smb_iconv_t) -1)
278 {
279 if (c1 != CH_UTF16LE && c1 != CH_UTF16BE)
280 {
281 n1 = "ASCII";
282 }
283 if (c2 != CH_UTF16LE && c2 != CH_UTF16BE)
284 {
285 n2 = "ASCII";
286 }
288 if (!conv_handles_ntlmssp[c1][c2])
289 {
290 g_message ("init_iconv_ntlmssp: conv_handle"
291 " initialization failed");
292 }
293 }
294 }
295 }
296
297 if (did_reload)
298 {
299 /* XXX: Does this really get called every time the dos
300 * codepage changes? */
301 /* XXX: Is the did_reload test too strict? */
305 }
306}
static const char * charset_name_ntlmssp(charset_t ch)
Definition charcnv.c:182
static void init_valid_table_ntlmssp(void)
Definition charcnv.c:124
#define True
Definition charcnv.c:64
#define NUM_CHARSETS
Definition charset.h:34
charset_t
Definition charset.h:24
@ CH_UNIX
Definition charset.h:27

References CH_UNIX, CH_UTF16BE, CH_UTF16LE, charset_name_ntlmssp(), conv_handles_ntlmssp, conv_silent_ntlmssp, False, init_valid_table_ntlmssp(), NUM_CHARSETS, smb_iconv_close_ntlmssp(), smb_iconv_open_ntlmssp(), and True.

Referenced by lazy_initialize_conv_ntlmssp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_valid_table_ntlmssp()

void init_valid_table_ntlmssp ( void )
static

Definition at line 124 of file charcnv.c.

125{
126 static int mapped_file;
127 int i;
128 const char *allowed = ".!#$%&'()_-@^`~";
129
130 if (mapped_file)
131 {
132 /* Can't unmap files, so stick with what we have */
133 return;
134 }
135
136 /* we're using a dynamically created valid_table.
137 * It might need to be regenerated if the code page changed.
138 * We know that we're not using a mapped file, so we can
139 * free() the old one. */
140
141 /* use free rather than unmap */
143
144 valid_table_ntlmssp = (uint8 *) SMB_MALLOC (0x10000);
145 for (i = 0; i < 128; i++)
146 {
147 valid_table_ntlmssp[i] = isalnum (i) || strchr (allowed, i);
148 }
149
151
152 for (; i < 0x10000; i++)
153 {
154 uint16_t c;
155 SSVAL (&c, 0, i);
157 }
158}
#define SSVAL(buf, pos, val)
Definition byteorder.h:116
#define uint8
Definition charcnv.c:45
static uint8 * valid_table_ntlmssp
Definition charcnv.c:66
static int check_dos_char_slowly_ntlmssp(uint16 c)
Definition charcnv.c:73
static bool valid_table_use_unmap_ntlmssp
Definition charcnv.c:67

References check_dos_char_slowly_ntlmssp(), False, lazy_initialize_conv_ntlmssp(), SSVAL, uint8, valid_table_ntlmssp, and valid_table_use_unmap_ntlmssp.

Referenced by init_iconv_ntlmssp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ lazy_initialize_conv_ntlmssp()

void lazy_initialize_conv_ntlmssp ( void )

Definition at line 226 of file charcnv.c.

227{
228 static int initialized = False;
229
230 if (!initialized)
231 {
232 initialized = True;
234 }
235}
void init_iconv_ntlmssp(void)
Definition charcnv.c:245

References False, init_iconv_ntlmssp(), and True.

Referenced by convert_string_internal_ntlmssp(), and init_valid_table_ntlmssp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ lp_failed_convert_char_ntlmssp()

char lp_failed_convert_char_ntlmssp ( void )
static

Definition at line 99 of file charcnv.c.

100{
101 return '_';
102}

Referenced by convert_string_internal_ntlmssp().

Here is the caller graph for this function:

◆ strlen_w_ntlmssp()

size_t strlen_w_ntlmssp ( const uint16 * src)
static

Definition at line 165 of file charcnv.c.

166{
167 size_t len;
168 uint16 c;
169
170 for (len = 0; *(COPY_UCS2_CHAR (&c, src)); src++, len++)
171 {
172 ;
173 }
174
175 return len;
176}
uint8_t len
#define COPY_UCS2_CHAR(dest, src)
Definition smb.h:164

References COPY_UCS2_CHAR, len, and uint16.

Referenced by convert_string_internal_ntlmssp().

Here is the caller graph for this function:

Variable Documentation

◆ conv_handles_ntlmssp

smb_iconv_t conv_handles_ntlmssp[NUM_CHARSETS][NUM_CHARSETS]
static

Definition at line 119 of file charcnv.c.

Referenced by convert_string_internal_ntlmssp(), and init_iconv_ntlmssp().

◆ conv_silent_ntlmssp

bool conv_silent_ntlmssp
static

Definition at line 121 of file charcnv.c.

Referenced by convert_string_internal_ntlmssp(), and init_iconv_ntlmssp().

◆ valid_table_ntlmssp

uint8* valid_table_ntlmssp
static

Definition at line 66 of file charcnv.c.

Referenced by init_valid_table_ntlmssp().

◆ valid_table_use_unmap_ntlmssp

bool valid_table_use_unmap_ntlmssp
static

Definition at line 67 of file charcnv.c.

Referenced by init_valid_table_ntlmssp().