1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
26 */
27
28 #if defined(_KERNEL) || defined(_FAKE_KERNEL)
29 #include <sys/types.h>
30 #include <sys/sunddi.h>
31 #else
32 #include <string.h>
33 #endif
34 #include <smbsrv/string.h>
35 #include <smbsrv/netbios.h>
36
37 static int domainname_is_valid(char *domain_name);
38
39 /*
40 * Routines than support name compression.
41 *
42 * The NetBIOS name representation in all NetBIOS packets (for NAME,
43 * SESSION, and DATAGRAM services) is defined in the Domain Name
44 * Service RFC 883[3] as "compressed" name messages. This format is
45 * called "second-level encoding" in the section entitled
46 * "Representation of NetBIOS Names" in the Concepts and Methods
47 * document.
48 *
49 * For ease of description, the first two paragraphs from page 31,
50 * the section titled "Domain name representation and compression",
51 * of RFC 883 are replicated here:
52 *
53 * Domain names messages are expressed in terms of a sequence
54 * of labels. Each label is represented as a one octet length
55 * field followed by that number of octets. Since every domain
56 * name ends with the null label of the root, a compressed
57 * domain name is terminated by a length byte of zero. The
58 * high order two bits of the length field must be zero, and
59 * the remaining six bits of the length field limit the label
60 * to 63 octets or less.
61 *
62 * To simplify implementations, the total length of label
63 * octets and label length octets that make up a domain name is
64 * restricted to 255 octets or less.
65 *
66 * The following is the uncompressed representation of the NetBIOS name
67 * "FRED ", which is the 4 ASCII characters, F, R, E, D, followed by 12
68 * space characters (0x20). This name has the SCOPE_ID: "NETBIOS.COM"
69 *
70 * EGFCEFEECACACACACACACACACACACACA.NETBIOS.COM
71 *
72 * This uncompressed representation of names is called "first-level
73 * encoding" in the section entitled "Representation of NetBIOS Names"
74 * in the Concepts and Methods document.
75 *
76 * The following is a pictographic representation of the compressed
77 * representation of the previous uncompressed Domain Name
78 * representation.
79 *
80 * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
81 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
82 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
83 * | 0x20 | E (0x45) | G (0x47) | F (0x46) |
84 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
85 * | C (0x43) | E (0x45) | F (0x46) | E (0x45) |
86 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
87 * | E (0x45) | C (0x43) | A (0x41) | C (0x43) |
88 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
89 * | A (0x41) | C (0x43) | A (0x41) | C (0x43) |
90 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
91 * | A (0x41) | C (0x43) | A (0x41) | C (0x43) |
92 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
93 * | A (0x41) | C (0x43) | A (0x41) | C (0x43) |
94 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
95 * | A (0x41) | C (0x43) | A (0x41) | C (0x43) |
96 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
97 * | A (0x41) | C (0x43) | A (0x41) | C (0x43) |
98 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99 * | A (0X41) | 0x07 | N (0x4E) | E (0x45) |
100 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101 * | T (0x54) | B (0x42) | I (0x49) | O (0x4F) |
102 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
103 * | S (0x53) | 0x03 | C (0x43) | O (0x4F) |
104 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105 * | M (0x4D) | 0x00 |
106 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
107 *
108 * Each section of a domain name is called a label [7 (page 31)]. A
109 * label can be a maximum of 63 bytes. The first byte of a label in
110 * compressed representation is the number of bytes in the label. For
111 * the above example, the first 0x20 is the number of bytes in the
112 * left-most label, EGFCEFEECACACACACACACACACACACACA, of the domain
113 * name. The bytes following the label length count are the characters
114 * of the label. The following labels are in sequence after the first
115 * label, which is the encoded NetBIOS name, until a zero (0x00) length
116 * count. The zero length count represents the root label, which is
117 * always null.
118 *
119 * A label length count is actually a 6-bit field in the label length
120 * field. The most significant 2 bits of the field, bits 7 and 6, are
121 * flags allowing an escape from the above compressed representation.
122 * If bits 7 and 6 are both set (11), the following 14 bits are an
123 * offset pointer into the full message to the actual label string from
124 * another domain name that belongs in this name. This label pointer
125 * allows for a further compression of a domain name in a packet.
126 *
127 * NetBIOS implementations can only use label string pointers in Name
128 * Service packets. They cannot be used in Session or Datagram Service
129 * packets.
130 *
131 * The other two possible values for bits 7 and 6 (01 and 10) of a label
132 * length field are reserved for future use by RFC 883[2 (page 32)].
133 *
134 * Note that the first octet of a compressed name must contain one of
135 * the following bit patterns. (An "x" indicates a bit whose value may
136 * be either 0 or 1.):
137 *
138 * 00100000 - Netbios name, length must be 32 (decimal)
139 * 11xxxxxx - Label string pointer
140 * 10xxxxxx - Reserved
141 * 01xxxxxx - Reserved
142 */
143
144 /*
145 * netbios_first_level_name_encode
146 *
147 * Put test description here.
148 *
149 * Inputs:
150 * char * in -> Name to encode
151 * char * out -> Buffer to encode into.
152 * int length -> # of bytes to encode.
153 *
154 * Returns:
155 * Nothing
156 */
157 int
netbios_first_level_name_encode(unsigned char * name,unsigned char * scope,unsigned char * out,int max_out)158 netbios_first_level_name_encode(unsigned char *name, unsigned char *scope,
159 unsigned char *out, int max_out)
160 {
161 unsigned char ch, len;
162 unsigned char *in;
163 unsigned char *lp;
164 unsigned char *op = out;
165
166 if (max_out < 0x21)
167 return (-1);
168
169 in = name;
170 *op++ = 0x20;
171 for (len = 0; len < NETBIOS_NAME_SZ; len++) {
172 ch = *in++;
173 *op++ = 'A' + ((ch >> 4) & 0xF);
174 *op++ = 'A' + ((ch) & 0xF);
175 }
176
177 max_out -= 0x21;
178
179 in = scope;
180 len = 0;
181 lp = op++;
182 while (((ch = *in++) != 0) && (max_out-- > 1)) {
183 if (ch == 0) {
184 if ((*lp = len) != 0)
185 *op++ = 0;
186 break;
187 }
188 if (ch == '.') {
189 *lp = len;
190 lp = op++;
191 len = 0;
192 } else {
193 *op++ = ch;
194 len++;
195 }
196 }
197 *lp = len;
198 if (len != 0)
199 *op = 0;
200
201 /*LINTED E_PTRDIFF_OVERFLOW*/
202 return (op - out);
203 }
204
205 /*
206 * smb_first_level_name_decode
207 *
208 * The null terminated string "in" is the name to decode. The output
209 * is placed in the name_entry structure "name".
210 *
211 * The scope field is a series of length designated labels as described
212 * in the "Domain name representation and compression" section of RFC883.
213 * The two high order two bits of the length field must be zero, the
214 * remaining six bits contain the field length. The total length of the
215 * domain name is restricted to 255 octets but note that the trailing
216 * root label and its dot are not printed. When converting the labels,
217 * the length fields are replaced by dots.
218 *
219 * Returns the number of bytes scanned or -1 to indicate an error.
220 */
221 int
netbios_first_level_name_decode(char * in,char * name,char * scope)222 netbios_first_level_name_decode(char *in, char *name, char *scope)
223 {
224 unsigned int length, bytes;
225 char c1, c2;
226 char *cp;
227 char *out;
228
229 cp = in;
230
231 if ((length = *cp++) != 0x20) {
232 return (-1);
233 }
234
235 out = name;
236 while (length > 0) {
237 c1 = *cp++;
238 c2 = *cp++;
239
240 if ('A' <= c1 && c1 <= 'P' && 'A' <= c2 && c2 <= 'P') {
241 c1 -= 'A';
242 c2 -= 'A';
243 *out++ = (c1 << 4) | (c2);
244 } else {
245 return (-1); /* conversion error */
246 }
247 length -= 2;
248 }
249
250 out = scope;
251 bytes = 0;
252 for (length = *cp++; length != 0; length = *cp++) {
253 if ((length & 0xc0) != 0x00) {
254 /*
255 * This is a pointer or a reserved field. If it's
256 * a pointer (16-bits) we have to skip the next byte.
257 */
258 if ((length & 0xc0) == 0xc0) {
259 cp++;
260 continue;
261 }
262 }
263
264 /*
265 * Replace the length with a '.', except for the first one.
266 */
267 if (out != scope) {
268 *out++ = '.';
269 bytes++;
270 }
271
272 while (length-- > 0) {
273 if (bytes++ >= (NETBIOS_DOMAIN_NAME_MAX - 1)) {
274 return (-1);
275 }
276 *out++ = *cp++;
277 }
278 }
279 *out = 0;
280
281 /*
282 * We are supposed to preserve all 8-bits of the domain name
283 * but due to the single byte representation in the name cache
284 * and UTF-8 encoding everywhere else, we restrict domain names
285 * to Appendix 1 - Domain Name Syntax Specification in RFC883.
286 */
287 if (domainname_is_valid(scope)) {
288 (void) smb_strupr(scope);
289 /*LINTED E_PTRDIFF_OVERFLOW*/
290 return (cp - in);
291 }
292
293 scope[0] = '\0';
294 return (-1);
295 }
296
297 /*
298 * smb_netbios_name_isvalid
299 *
300 * This function is provided to be used by session service
301 * which runs in kernel in order to hide name_entry definition.
302 *
303 * It returns the decoded name in the provided buffer as 'out'
304 * if it's not null.
305 *
306 * Returns 0 if decode fails, 1 if it succeeds.
307 */
308 int
netbios_name_isvalid(char * in,char * out)309 netbios_name_isvalid(char *in, char *out)
310 {
311 char name[NETBIOS_NAME_SZ];
312 char scope[NETBIOS_DOMAIN_NAME_MAX];
313
314 if (netbios_first_level_name_decode(in, name, scope) < 0)
315 return (0);
316
317 if (out)
318 (void) strlcpy(out, name, NETBIOS_NAME_SZ);
319
320 return (1);
321 }
322
323 /*
324 * Characters that we allow in DNS domain names, in addition to
325 * alphanumeric characters. This is not quite consistent with
326 * RFC883. This is global so that it can be patched if there is
327 * a need to change the valid characters in the field.
328 */
329 static const char dns_allowed[] = "-_";
330
331 /*
332 * dns_is_allowed
333 *
334 * Check the dns_allowed characters and return true (1) if the character
335 * is in the table. Otherwise return false (0).
336 */
337 static int
dns_is_allowed(unsigned char c)338 dns_is_allowed(unsigned char c)
339 {
340 const char *p = dns_allowed;
341
342 while (*p) {
343 if ((char)c == *p++)
344 return (1);
345 }
346
347 return (0);
348 }
349
350
351 /*
352 * domainname_is_valid
353 *
354 * Check the specified domain name for mostly compliance with RFC883
355 * Appendix 1. Names may contain alphanumeric characters, hyphens,
356 * underscores and dots. The first character after a dot must be an
357 * alphabetic character. RFC883 doesn't mention underscores but we
358 * allow it due to common use, and we don't check that labels end
359 * with an alphanumeric character.
360 *
361 * Returns true (1) if the name is valid. Otherwise returns false (0).
362 */
363 static int
domainname_is_valid(char * domain_name)364 domainname_is_valid(char *domain_name)
365 {
366 char *name;
367 int first_char = 1;
368
369 if (domain_name == 0)
370 return (0);
371
372 for (name = domain_name; *name != 0; ++name) {
373 if (*name == '.') {
374 first_char = 1;
375 continue;
376 }
377
378 if (first_char) {
379 if (smb_isalpha_ascii(*name) == 0)
380 return (0);
381
382 first_char = 0;
383 continue;
384 }
385
386 if (smb_isalnum_ascii(*name) || dns_is_allowed(*name))
387 continue;
388
389 return (0);
390 }
391
392 return (1);
393 }
394