OpenVAS Libraries  9.0.3
iconv.c
Go to the documentation of this file.
1 /*
2  Unix SMB/CIFS implementation.
3  minimal iconv implementation
4  Copyright (C) Andrew Tridgell 2001
5  Copyright (C) Jelmer Vernooij 2002,2003
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21 /* Modified by Preeti Subramanian <spreeti@secpod.com>
22  * Modifications:
23  * *Some functions removed which are not required for Openvas
24  * *In smb_iconv_open function, check for module available to
25  * do the conversion is not required(removed)
26  */
27 
28 #include "iconv.h"
29 #include "charset.h"
30 #include "smb.h"
31 
32 typedef unsigned int bool;
33 
34 static size_t iconv_copy_ntlmssp(void *,const char **, size_t *, char **, size_t *);
35 
36 static struct charset_functions_ntlmssp *charsets = NULL;
37 
38 static struct charset_functions_ntlmssp *find_charset_functions_ntlmssp(const char *name)
39 {
40  struct charset_functions_ntlmssp *c = charsets;
41 
42  while(c) {
43  if (strcasecmp(name, c->name) == 0) {
44  return c;
45  }
46  c = c->next;
47  }
48 
49  return NULL;
50 }
51 
60  const char **inbuf, size_t *inbytesleft,
61  char **outbuf, size_t *outbytesleft)
62 {
63  char cvtbuf[2048];
64  char *bufp = cvtbuf;
65  size_t bufsize;
66 
67  /* in many cases we can go direct */
68  if (cd->direct) {
69  return cd->direct(cd->cd_direct,
70  inbuf, inbytesleft, outbuf, outbytesleft);
71  }
72 
73 
74  /* otherwise we have to do it chunks at a time */
75  while (*inbytesleft > 0) {
76  bufp = cvtbuf;
77  bufsize = sizeof(cvtbuf);
78 
79  if (cd->pull(cd->cd_pull,
80  inbuf, inbytesleft, &bufp, &bufsize) == -1
81  && errno != E2BIG) return -1;
82 
83  bufp = cvtbuf;
84  bufsize = sizeof(cvtbuf) - bufsize;
85 
86  if (cd->push(cd->cd_push,
87  (const char **)&bufp, &bufsize,
88  outbuf, outbytesleft) == -1) return -1;
89  }
90 
91  return 0;
92 }
93 
94 
95 static bool is_utf16_ntlmssp(const char *name)
96 {
97  return strcasecmp(name, "UCS-2LE") == 0 ||
98  strcasecmp(name, "UTF-16LE") == 0;
99 }
100 
101 
102 /*
103  simple iconv_open() wrapper
104  */
105 smb_iconv_t smb_iconv_open_ntlmssp(const char *tocode, const char *fromcode)
106 {
107  smb_iconv_t ret;
108  struct charset_functions_ntlmssp *from, *to;
109 
110  ret = SMB_MALLOC_P(struct _smb_iconv_t);
111  if (!ret) {
112  errno = ENOMEM;
113  return (smb_iconv_t)-1;
114  }
115  memset(ret, 0, sizeof(struct _smb_iconv_t));
116 
117  ret->from_name = SMB_STRDUP(fromcode);
118  ret->to_name = SMB_STRDUP(tocode);
119 
120  /* check for the simplest null conversion */
121  if (strcasecmp(fromcode, tocode) == 0) {
122  ret->direct = iconv_copy_ntlmssp;
123  return ret;
124  }
125 
126  /* check if we have a builtin function for this conversion */
127  from = find_charset_functions_ntlmssp(fromcode);
128  if(from)ret->pull = from->pull;
129 
130  to = find_charset_functions_ntlmssp(tocode);
131  if(to)ret->push = to->push;
132 
133  /* check if we can use iconv for this conversion */
134 #ifdef HAVE_NATIVE_ICONV
135  if (!ret->pull) {
136  ret->cd_pull = iconv_open("UTF-16LE", fromcode);
137  if (ret->cd_pull == (iconv_t)-1)
138  ret->cd_pull = iconv_open("UCS-2LE", fromcode);
139  if (ret->cd_pull != (iconv_t)-1)
140  ret->pull = sys_iconv;
141  }
142 
143  if (!ret->push) {
144  ret->cd_push = iconv_open(tocode, "UTF-16LE");
145  if (ret->cd_push == (iconv_t)-1)
146  ret->cd_push = iconv_open(tocode, "UCS-2LE");
147  if (ret->cd_push != (iconv_t)-1)
148  ret->push = sys_iconv;
149  }
150 #endif
151 
152  if (!ret->push || !ret->pull) {
153  SAFE_FREE(ret->from_name);
154  SAFE_FREE(ret->to_name);
155  SAFE_FREE(ret);
156  errno = EINVAL;
157  return (smb_iconv_t)-1;
158  }
159 
160  /* check for conversion to/from ucs2 */
161  if (is_utf16_ntlmssp(fromcode) && to) {
162  ret->direct = to->push;
163  ret->push = ret->pull = NULL;
164  return ret;
165  }
166 
167  if (is_utf16_ntlmssp(tocode) && from) {
168  ret->direct = from->pull;
169  ret->push = ret->pull = NULL;
170  return ret;
171  }
172 
173  /* Check if we can do the conversion direct */
174 #ifdef HAVE_NATIVE_ICONV
175  if (is_utf16(fromcode)) {
176  ret->direct = sys_iconv;
177  ret->cd_direct = ret->cd_push;
178  ret->cd_push = NULL;
179  return ret;
180  }
181  if (is_utf16(tocode)) {
182  ret->direct = sys_iconv;
183  ret->cd_direct = ret->cd_pull;
184  ret->cd_pull = NULL;
185  return ret;
186  }
187 #endif
188 
189  return ret;
190 }
191 
192 /*
193  simple iconv_close() wrapper
194 */
196 {
197 #ifdef HAVE_NATIVE_ICONV
198  if (cd->cd_direct) iconv_close((iconv_t)cd->cd_direct);
199  if (cd->cd_pull) iconv_close((iconv_t)cd->cd_pull);
200  if (cd->cd_push) iconv_close((iconv_t)cd->cd_push);
201 #endif
202 
203  SAFE_FREE(cd->from_name);
204  SAFE_FREE(cd->to_name);
205 
206  memset(cd, 0, sizeof(*cd));
207  SAFE_FREE(cd);
208  return 0;
209 }
210 
211 static size_t iconv_copy_ntlmssp(void *cd, const char **inbuf, size_t *inbytesleft,
212  char **outbuf, size_t *outbytesleft)
213 {
214  int n;
215 
216  n = MIN(*inbytesleft, *outbytesleft);
217 
218  memmove(*outbuf, *inbuf, n);
219 
220  (*inbytesleft) -= n;
221  (*outbytesleft) -= n;
222  (*inbuf) += n;
223  (*outbuf) += n;
224 
225  if (*inbytesleft > 0) {
226  errno = E2BIG;
227  return -1;
228  }
229 
230  return 0;
231 }
232 
233 
struct charset_functions_ntlmssp * next
Definition: charset.h:44
void * cd_pull
Definition: smb.h:90
size_t(* push)(void *, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: charset.h:42
char * to_name
Definition: smb.h:91
size_t(* pull)(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: smb.h:86
size_t(* direct)(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: smb.h:84
size_t(* push)(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: smb.h:88
unsigned int bool
Definition: iconv.c:32
smb_iconv_t smb_iconv_open_ntlmssp(const char *tocode, const char *fromcode)
Definition: iconv.c:105
size_t(* pull)(void *, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: charset.h:40
const char * name
Definition: charset.h:39
void * cd_direct
Definition: smb.h:90
size_t smb_iconv_ntlmssp(smb_iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: iconv.c:59
#define SMB_MALLOC_P(type)
Definition: smb.h:171
void * cd_push
Definition: smb.h:90
const char * name
Definition: nasl_init.c:524
#define SAFE_FREE(x)
Definition: hmacmd5.h:49
int smb_iconv_close_ntlmssp(smb_iconv_t cd)
Definition: iconv.c:195
#define SMB_STRDUP(s)
Definition: smb.h:178
char * from_name
Definition: smb.h:91