OpenVAS Scanner  7.0.1~git
iconv.c
Go to the documentation of this file.
1 /* Portions Copyright (C) 2009-2019 Greenbone Networks GmbH
2  * Copyright (C) Andrew Tridgell 2001
3  * Copyright (C) Jelmer Vernooij 2002,2003
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
27 #include "iconv.h"
28 
29 #include "charset.h"
30 #include "smb.h"
31 
32 #include <glib.h>
33 
34 typedef unsigned int bool;
35 
36 static size_t
37 iconv_copy_ntlmssp (void *, const char **, size_t *, char **, size_t *);
38 
39 static struct charset_functions_ntlmssp *charsets = NULL;
40 
41 static struct charset_functions_ntlmssp *
43 {
45 
46  while (c)
47  {
48  if (strcasecmp (name, c->name) == 0)
49  {
50  return c;
51  }
52  c = c->next;
53  }
54 
55  return NULL;
56 }
57 
65 size_t
66 smb_iconv_ntlmssp (smb_iconv_t cd, const char **inbuf, size_t *inbytesleft,
67  char **outbuf, size_t *outbytesleft)
68 {
69  char cvtbuf[2048];
70  char *bufp = cvtbuf;
71  size_t bufsize;
72 
73  /* in many cases we can go direct */
74  if (cd->direct)
75  {
76  return cd->direct (cd->cd_direct, inbuf, inbytesleft, outbuf,
77  outbytesleft);
78  }
79 
80  /* otherwise we have to do it chunks at a time */
81  while (*inbytesleft > 0)
82  {
83  bufp = cvtbuf;
84  bufsize = sizeof (cvtbuf);
85 
86  if (cd->pull (cd->cd_pull, inbuf, inbytesleft, &bufp, &bufsize)
87  == (size_t) -1
88  && errno != E2BIG)
89  return -1;
90 
91  bufp = cvtbuf;
92  bufsize = sizeof (cvtbuf) - bufsize;
93 
94  if (cd->push (cd->cd_push, (const char **) &bufp, &bufsize, outbuf,
95  outbytesleft)
96  == (size_t) -1)
97  return -1;
98  }
99 
100  return 0;
101 }
102 
103 static bool
104 is_utf16_ntlmssp (const char *name)
105 {
106  return strcasecmp (name, "UCS-2LE") == 0
107  || strcasecmp (name, "UTF-16LE") == 0;
108 }
109 
110 /*
111  simple iconv_open() wrapper
112  */
114 smb_iconv_open_ntlmssp (const char *tocode, const char *fromcode)
115 {
116  smb_iconv_t ret;
117  struct charset_functions_ntlmssp *from, *to;
118 
119  ret = SMB_MALLOC_P (struct _smb_iconv_t);
120  if (!ret)
121  {
122  errno = ENOMEM;
123  return (smb_iconv_t) -1;
124  }
125  memset (ret, 0, sizeof (struct _smb_iconv_t));
126 
127  ret->from_name = SMB_STRDUP (fromcode);
128  ret->to_name = SMB_STRDUP (tocode);
129 
130  /* check for the simplest null conversion */
131  if (strcasecmp (fromcode, tocode) == 0)
132  {
133  ret->direct = iconv_copy_ntlmssp;
134  return ret;
135  }
136 
137  /* check if we have a builtin function for this conversion */
138  from = find_charset_functions_ntlmssp (fromcode);
139  if (from)
140  ret->pull = from->pull;
141 
142  to = find_charset_functions_ntlmssp (tocode);
143  if (to)
144  ret->push = to->push;
145 
146  /* check if we can use iconv for this conversion */
147 #ifdef HAVE_NATIVE_ICONV
148  if (!ret->pull)
149  {
150  ret->cd_pull = iconv_open ("UTF-16LE", fromcode);
151  if (ret->cd_pull == (iconv_t) -1)
152  ret->cd_pull = iconv_open ("UCS-2LE", fromcode);
153  if (ret->cd_pull != (iconv_t) -1)
154  ret->pull = sys_iconv;
155  }
156 
157  if (!ret->push)
158  {
159  ret->cd_push = iconv_open (tocode, "UTF-16LE");
160  if (ret->cd_push == (iconv_t) -1)
161  ret->cd_push = iconv_open (tocode, "UCS-2LE");
162  if (ret->cd_push != (iconv_t) -1)
163  ret->push = sys_iconv;
164  }
165 #endif
166 
167  if (!ret->push || !ret->pull)
168  {
169  g_free (ret->from_name);
170  g_free (ret->to_name);
171  g_free (ret);
172  errno = EINVAL;
173  return (smb_iconv_t) -1;
174  }
175 
176  /* check for conversion to/from ucs2 */
177  if (is_utf16_ntlmssp (fromcode) && to)
178  {
179  ret->direct = to->push;
180  ret->push = ret->pull = NULL;
181  return ret;
182  }
183 
184  if (is_utf16_ntlmssp (tocode) && from)
185  {
186  ret->direct = from->pull;
187  ret->push = ret->pull = NULL;
188  return ret;
189  }
190 
191  /* Check if we can do the conversion direct */
192 #ifdef HAVE_NATIVE_ICONV
193  if (is_utf16 (fromcode))
194  {
195  ret->direct = sys_iconv;
196  ret->cd_direct = ret->cd_push;
197  ret->cd_push = NULL;
198  return ret;
199  }
200  if (is_utf16 (tocode))
201  {
202  ret->direct = sys_iconv;
203  ret->cd_direct = ret->cd_pull;
204  ret->cd_pull = NULL;
205  return ret;
206  }
207 #endif
208 
209  return ret;
210 }
211 
212 /*
213  simple iconv_close() wrapper
214 */
215 int
217 {
218 #ifdef HAVE_NATIVE_ICONV
219  if (cd->cd_direct)
220  iconv_close ((iconv_t) cd->cd_direct);
221  if (cd->cd_pull)
222  iconv_close ((iconv_t) cd->cd_pull);
223  if (cd->cd_push)
224  iconv_close ((iconv_t) cd->cd_push);
225 #endif
226 
227  g_free (cd->from_name);
228  g_free (cd->to_name);
229 
230  memset (cd, 0, sizeof (*cd));
231  g_free (cd);
232  return 0;
233 }
234 
235 static size_t
236 iconv_copy_ntlmssp (void *cd, const char **inbuf, size_t *inbytesleft,
237  char **outbuf, size_t *outbytesleft)
238 {
239  int n;
240 
241  n = MIN (*inbytesleft, *outbytesleft);
242 
243  (void) cd;
244  memmove (*outbuf, *inbuf, n);
245 
246  (*inbytesleft) -= n;
247  (*outbytesleft) -= n;
248  (*inbuf) += n;
249  (*outbuf) += n;
250 
251  if (*inbytesleft > 0)
252  {
253  errno = E2BIG;
254  return -1;
255  }
256 
257  return 0;
258 }
struct charset_functions_ntlmssp * next
Definition: charset.h:60
void * cd_pull
Definition: smb.h:95
size_t(* push)(void *, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: charset.h:58
char * to_name
Definition: smb.h:96
static size_t iconv_copy_ntlmssp(void *, const char **, size_t *, char **, size_t *)
Definition: iconv.c:236
Unix SMB/CIFS implementation. charset defines.
size_t(* pull)(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: smb.h:91
size_t(* direct)(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: smb.h:89
size_t(* push)(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: smb.h:93
unsigned int bool
Definition: iconv.c:34
smb_iconv_t smb_iconv_open_ntlmssp(const char *tocode, const char *fromcode)
Definition: iconv.c:114
size_t(* pull)(void *, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: charset.h:56
const char * name
Definition: charset.h:55
void * cd_direct
Definition: smb.h:95
size_t smb_iconv_ntlmssp(smb_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: iconv.c:66
Unix SMB/CIFS implementation.
#define SMB_MALLOC_P(type)
Definition: smb.h:186
void * cd_push
Definition: smb.h:95
static struct charset_functions_ntlmssp * charsets
Definition: iconv.c:39
const char * name
Definition: nasl_init.c:377
static bool is_utf16_ntlmssp(const char *name)
Definition: iconv.c:104
int smb_iconv_close_ntlmssp(smb_iconv_t cd)
Definition: iconv.c:216
Unix SMB/CIFS implementation. iconv memory system include wrappers.
#define SMB_STRDUP(s)
Definition: smb.h:194
char * from_name
Definition: smb.h:96
static struct charset_functions_ntlmssp * find_charset_functions_ntlmssp(const char *name)
Definition: iconv.c:42