1/*
2 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 */
5
6#pragma ident	"%Z%%M%	%I%	%E% SMI"
7
8/* decode.c - ber input decoding routines */
9/*
10 * Copyright (c) 1990 Regents of the University of Michigan.
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms are permitted
14 * provided that this notice is preserved and that due credit is given
15 * to the University of Michigan at Ann Arbor. The name of the University
16 * may not be used to endorse or promote products derived from this
17 * software without specific prior written permission. This software
18 * is provided ``as is'' without express or implied warranty.
19 */
20
21#include <stdio.h>
22#ifdef MACOS
23#include <stdlib.h>
24#include <stdarg.h>
25#include "macos.h"
26#else /* MACOS */
27#if defined(NeXT) || defined(VMS)
28#include <stdlib.h>
29#else /* next || vms */
30#include <malloc.h>
31#endif /* next || vms */
32#if defined(BC31) || defined(_WIN32) || defined(__sun)
33#include <stdarg.h>
34#else /* BC31 || _WIN32 */
35#include <varargs.h>
36#endif /* BC31 || _WIN32 */
37#include <sys/types.h>
38#include <sys/socket.h>
39#include <netinet/in.h>
40#ifdef PCNFS
41#include <tklib.h>
42#endif /* PCNFS */
43#endif /* MACOS */
44
45#if defined( DOS ) || defined( _WIN32 )
46#include "msdos.h"
47#endif /* DOS */
48
49#include <string.h>
50#include "lber.h"
51#include "ldap.h"
52#include "ldap-private.h"
53#include "ldap-int.h"
54
55#ifdef LDAP_DEBUG
56int	lber_debug;
57#endif
58
59#ifdef NEEDPROTOS
60static int ber_getnint( BerElement *ber, int *num, int len );
61#endif /* NEEDPROTOS */
62
63
64/* return the tag - LBER_DEFAULT returned means trouble */
65unsigned int
66ber_get_tag( BerElement *ber )
67{
68	unsigned char	xbyte;
69	unsigned int	tag;
70	char		*tagp;
71	int		i;
72
73	if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 )
74		return( LBER_DEFAULT );
75
76	if ( (xbyte & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK )
77		return( (unsigned int) xbyte );
78
79	tagp = (char *) &tag;
80	tagp[0] = xbyte;
81	for ( i = 1; i < sizeof(int); i++ ) {
82		if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 )
83			return( LBER_DEFAULT );
84
85		tagp[i] = xbyte;
86
87		if ( ! (xbyte & LBER_MORE_TAG_MASK) )
88			break;
89	}
90
91	/* tag too big! */
92	if ( i == sizeof(int) )
93		return( LBER_DEFAULT );
94
95	/* want leading, not trailing 0's */
96	return( tag >> (sizeof(int) - i - 1) );
97}
98
99unsigned int
100ber_skip_tag( BerElement *ber, unsigned int *len )
101{
102	unsigned int	tag;
103	unsigned char	lc;
104	int		noctets, diff;
105	unsigned int	netlen;
106
107	/*
108	 * Any ber element looks like this: tag length contents.
109	 * Assuming everything's ok, we return the tag byte (we
110	 * can assume a single byte), and return the length in len.
111	 *
112	 * Assumptions:
113	 *	1) definite lengths
114	 *	2) primitive encodings used whenever possible
115	 */
116
117	/*
118	 * First, we read the tag.
119	 */
120
121	if ( (tag = ber_get_tag( ber )) == LBER_DEFAULT )
122		return( LBER_DEFAULT );
123
124	/*
125	 * Next, read the length.  The first byte contains the length of
126	 * the length.  If bit 8 is set, the length is the int form,
127	 * otherwise it's the short form.  We don't allow a length that's
128	 * greater than what we can hold in an unsigned int.
129	 */
130
131	*len = netlen = 0;
132	if ( ber_read( ber, (char *) &lc, 1 ) != 1 )
133		return( LBER_DEFAULT );
134	if ( lc & 0x80 ) {
135		noctets = (lc & 0x7f);
136		if ( noctets > sizeof(unsigned int) )
137			return( LBER_DEFAULT );
138		diff = (int)sizeof(unsigned int) - noctets;
139		if ( ber_read( ber, (char *) &netlen + diff, noctets )
140		    != noctets )
141			return( LBER_DEFAULT );
142		*len = LBER_NTOHL( netlen );
143	} else {
144		*len = lc;
145	}
146
147	return( tag );
148}
149
150unsigned int
151ber_peek_tag( BerElement *ber, unsigned int *len )
152{
153	char		*save;
154	unsigned int	tag;
155
156	save = ber->ber_ptr;
157	tag = ber_skip_tag( ber, len );
158	ber->ber_ptr = save;
159
160	return( tag );
161}
162
163static int
164ber_getnint( BerElement *ber, int *num, int len )
165{	/* New patch much cleaner, from David Wilson, Isode. Old code not kept*/
166 	int	i;
167 	unsigned char buffer[sizeof(int)];
168 	int	value;
169
170  	/*
171  	 * The tag and length have already been stripped off.  We should
172  	 * be sitting right before len bytes of 2's complement integer,
173 	 * ready to be read straight into an int.
174  	 */
175
176  	if ( len > sizeof(int) )
177  		return( -1 );
178
179 	if ( ber_read( ber, (char *) buffer, len ) != len )
180  		return( -1 );
181
182 	/* This sets the required sign extension */
183 	value = 0x80 & buffer[0] ? (-1) : 0;
184
185 	for ( i = 0; i < len; i++ )
186 	    value = (value << 8) | buffer[i];
187
188	*num = value;
189
190  	return( len );
191}
192
193unsigned int
194ber_get_int( BerElement *ber, int *num )
195{
196	unsigned int	tag, len;
197
198	if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
199		return( LBER_DEFAULT );
200
201	if ( ber_getnint( ber, num, (int)len ) != len )
202		return( LBER_DEFAULT );
203	else
204		return( tag );
205}
206
207unsigned int
208ber_get_stringb( BerElement *ber, char *buf, unsigned int *len )
209{
210	unsigned int	datalen, tag;
211#ifdef STR_TRANSLATION
212	char		*transbuf;
213#endif /* STR_TRANSLATION */
214
215	if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT )
216		return( LBER_DEFAULT );
217	if ( datalen > (*len - 1) )
218		return( LBER_DEFAULT );
219
220	if ( ber_read( ber, buf, datalen ) != datalen )
221		return( LBER_DEFAULT );
222
223	buf[datalen] = '\0';
224
225#ifdef STR_TRANSLATION
226	if ( datalen > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0
227	    && ber->ber_decode_translate_proc != NULL ) {
228		transbuf = buf;
229		++datalen;
230		if ( (*(ber->ber_decode_translate_proc))( &transbuf, &datalen,
231		    0 ) != 0 ) {
232			return( LBER_DEFAULT );
233		}
234		if ( datalen > *len ) {
235			free( transbuf );
236			return( LBER_DEFAULT );
237		}
238		(void) SAFEMEMCPY( buf, transbuf, datalen );
239		free( transbuf );
240		--datalen;
241	}
242#endif /* STR_TRANSLATION */
243
244	*len = datalen;
245	return( tag );
246}
247
248unsigned int
249ber_get_stringa( BerElement *ber, char **buf )
250{
251	unsigned int	datalen, tag;
252
253	if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT )
254		return( LBER_DEFAULT );
255
256	if ( (*buf = (char *) malloc( (size_t)datalen + 1 )) == NULL )
257		return( LBER_DEFAULT );
258
259	if ( ber_read( ber, *buf, datalen ) != datalen )
260		return( LBER_DEFAULT );
261	(*buf)[datalen] = '\0';
262
263#ifdef STR_TRANSLATION
264	if ( datalen > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0
265	    && ber->ber_decode_translate_proc != NULL ) {
266		++datalen;
267		if ( (*(ber->ber_decode_translate_proc))( buf, &datalen, 1 )
268		    != 0 ) {
269			free( *buf );
270			return( LBER_DEFAULT );
271		}
272	}
273#endif /* STR_TRANSLATION */
274
275	return( tag );
276}
277
278unsigned int
279ber_get_stringal( BerElement *ber, struct berval **bv )
280{
281	unsigned int	len, tag;
282
283	if ( (*bv = (struct berval *) malloc( sizeof(struct berval) )) == NULL )
284		return( LBER_DEFAULT );
285
286	if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
287		return( LBER_DEFAULT );
288
289	if ( ((*bv)->bv_val = (char *) malloc( (size_t)len + 1 )) == NULL )
290		return( LBER_DEFAULT );
291
292	if ( ber_read( ber, (*bv)->bv_val, len ) != len )
293		return( LBER_DEFAULT );
294	((*bv)->bv_val)[len] = '\0';
295	(*bv)->bv_len = len;
296
297#ifdef STR_TRANSLATION
298	if ( len > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0
299	    && ber->ber_decode_translate_proc != NULL ) {
300		++len;
301		if ( (*(ber->ber_decode_translate_proc))( &((*bv)->bv_val),
302		    &len, 1 ) != 0 ) {
303			free( (*bv)->bv_val );
304			return( LBER_DEFAULT );
305		}
306		(*bv)->bv_len = len - 1;
307	}
308#endif /* STR_TRANSLATION */
309
310	return( tag );
311}
312
313unsigned int
314ber_get_bitstringa( BerElement *ber, char **buf, unsigned int *blen )
315{
316	unsigned int	datalen, tag;
317	unsigned char	unusedbits;
318
319	if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT )
320		return( LBER_DEFAULT );
321	--datalen;
322
323	if ( (*buf = (char *) malloc( (size_t)datalen )) == NULL )
324		return( LBER_DEFAULT );
325
326	if ( ber_read( ber, (char *)&unusedbits, 1 ) != 1 )
327		return( LBER_DEFAULT );
328
329	if ( ber_read( ber, *buf, datalen ) != datalen )
330		return( LBER_DEFAULT );
331
332	*blen = datalen * 8 - unusedbits;
333	return( tag );
334}
335
336unsigned int
337ber_get_null( BerElement *ber )
338{
339	unsigned int	len, tag;
340
341	if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
342		return( LBER_DEFAULT );
343
344	if ( len != 0 )
345		return( LBER_DEFAULT );
346
347	return( tag );
348}
349
350unsigned int
351ber_get_boolean( BerElement *ber, int *boolval )
352{
353	int	longbool;
354	int	rc;
355
356	rc = ber_get_int( ber, &longbool );
357	*boolval = longbool;
358
359	return( rc );
360}
361
362unsigned int
363ber_first_element( BerElement *ber, unsigned int *len, char **last )
364{
365	/* skip the sequence header, use the len to mark where to stop */
366	if ( ber_skip_tag( ber, len ) == LBER_DEFAULT ) {
367		return( LBER_DEFAULT );
368	}
369
370	*last = ber->ber_ptr + *len;
371
372	if ( *last == ber->ber_ptr ) {
373		return( LBER_DEFAULT );
374	}
375
376	return( ber_peek_tag( ber, len ) );
377}
378
379unsigned int
380ber_next_element( BerElement *ber, unsigned int *len, char *last )
381{
382	if ( ber->ber_ptr == last ) {
383		return( LBER_DEFAULT );
384	}
385
386	return( ber_peek_tag( ber, len ) );
387}
388
389/* VARARGS */
390unsigned int
391ber_scanf(
392#if defined(MACOS) || defined(BC31) || defined(_WIN32) || defined(__sun)
393	BerElement *ber, char *fmt, ... )
394#else
395	va_alist )
396va_dcl
397#endif
398{
399	va_list		ap;
400#if !defined(MACOS) && !defined(BC31) && !defined(_WIN32) && !defined(__sun)
401	BerElement	*ber;
402	char		*fmt;
403#endif
404	char		*last;
405	char		*s, **ss, ***sss;
406	struct berval 	***bv, **bvp, *bval;
407	int		*i, j;
408	int		*l, rc, tag;
409	unsigned int	len;
410
411#if defined(MACOS) || defined(BC31) || defined(_WIN32) || defined(__sun)
412	va_start( ap, fmt );
413#else
414	va_start( ap );
415	ber = va_arg( ap, BerElement * );
416	fmt = va_arg( ap, char * );
417#endif
418
419#ifdef LDAP_DEBUG
420	if ( lber_debug & 64 ) {
421		(void) fprintf( stderr, catgets(slapdcat, 1, 73, "ber_scanf fmt (%s) ber:\n"), fmt );
422		ber_dump( ber, 1 );
423	}
424#endif
425
426	for ( rc = 0; *fmt && rc != LBER_DEFAULT; fmt++ ) {
427		switch ( *fmt ) {
428		case 'a':	/* octet string - allocate storage as needed */
429			ss = va_arg( ap, char ** );
430			rc = ber_get_stringa( ber, ss );
431			break;
432
433		case 'b':	/* boolean */
434			i = va_arg( ap, int * );
435			rc = ber_get_boolean( ber, i );
436			break;
437
438		case 'e':	/* enumerated */
439		case 'i':	/* int */
440			l = va_arg( ap, int * );
441			rc = ber_get_int( ber, l );
442			break;
443
444		case 'l':	/* length of next item */
445			l = va_arg( ap, int * );
446			rc = ber_peek_tag( ber, (unsigned int *)l );
447			break;
448
449		case 'n':	/* null */
450			rc = ber_get_null( ber );
451			break;
452
453		case 's':	/* octet string - in a buffer */
454			s = va_arg( ap, char * );
455			l = va_arg( ap, int * );
456			rc = ber_get_stringb( ber, s, (unsigned int *)l );
457			break;
458
459		case 'o':	/* octet string in a supplied berval */
460			bval = va_arg( ap, struct berval * );
461			ber_peek_tag( ber, &bval->bv_len );
462			rc = ber_get_stringa( ber, &bval->bv_val );
463			break;
464
465		case 'O':	/* octet string - allocate & include length */
466			bvp = va_arg( ap, struct berval ** );
467			rc = ber_get_stringal( ber, bvp );
468			break;
469
470		case 'B':	/* bit string - allocate storage as needed */
471			ss = va_arg( ap, char ** );
472			l = va_arg( ap, int * ); /* for length, in bits */
473			rc = ber_get_bitstringa( ber, ss, (unsigned int *)l );
474			break;
475
476		case 't':	/* tag of next item */
477			i = va_arg( ap, int * );
478			*i = rc = ber_peek_tag( ber, &len );
479			break;
480
481		case 'T':	/* skip tag of next item */
482			i = va_arg( ap, int * );
483			*i = rc = ber_skip_tag( ber, &len );
484			break;
485
486		case 'v':	/* sequence of strings */
487			sss = va_arg( ap, char *** );
488			*sss = NULL;
489			j = 0;
490			for ( tag = ber_first_element( ber, &len, &last );
491			    tag != LBER_DEFAULT && rc != LBER_DEFAULT;
492			    tag = ber_next_element( ber, &len, last ) ) {
493				if ( *sss == NULL ) {
494					*sss = (char **) malloc(
495					    2 * sizeof(char *) );
496				} else {
497					*sss = (char **) realloc( *sss,
498					    (j + 2) * sizeof(char *) );
499				}
500				rc = ber_get_stringa( ber, &((*sss)[j]) );
501				j++;
502			}
503			if ( j > 0 )
504				(*sss)[j] = NULL;
505			break;
506
507		case 'V':	/* sequence of strings + lengths */
508			bv = va_arg( ap, struct berval *** );
509			*bv = NULL;
510			j = 0;
511			for ( tag = ber_first_element( ber, &len, &last );
512			    tag != LBER_DEFAULT && rc != LBER_DEFAULT;
513			    tag = ber_next_element( ber, &len, last ) ) {
514				if ( *bv == NULL ) {
515					*bv = (struct berval **) malloc(
516					    2 * sizeof(struct berval *) );
517				} else {
518					*bv = (struct berval **) realloc( *bv,
519					    (j + 2) * sizeof(struct berval *) );
520				}
521				rc = ber_get_stringal( ber, &((*bv)[j]) );
522				j++;
523			}
524			if ( j > 0 )
525				(*bv)[j] = NULL;
526			break;
527
528		case 'x':	/* skip the next element - whatever it is */
529			if ( (rc = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
530				break;
531			ber->ber_ptr += len;
532			break;
533
534		case '{':	/* begin sequence */
535		case '[':	/* begin set */
536			if ( *(fmt + 1) != 'v' && *(fmt + 1) != 'V' )
537				rc = ber_skip_tag( ber, &len );
538			break;
539
540		case '}':	/* end sequence */
541		case ']':	/* end set */
542			break;
543
544		default:
545#ifndef NO_USERINTERFACE
546			(void) fprintf( stderr, catgets(slapdcat, 1, 74, "unknown fmt %c\n"), *fmt );
547#endif /* NO_USERINTERFACE */
548			rc = (int) LBER_DEFAULT;
549			break;
550		}
551	}
552
553	va_end( ap );
554
555	return( rc );
556}
557
558void
559ber_bvfree( struct berval *bv )
560{
561	if ( bv->bv_val != NULL )
562		free( bv->bv_val );
563	free( (char *) bv );
564}
565
566void
567ber_bvecfree( struct berval **bv )
568{
569	int	i;
570
571	for ( i = 0; bv[i] != NULL; i++ )
572		ber_bvfree( bv[i] );
573	free( (char *) bv );
574}
575
576struct berval *
577ber_bvdup( struct berval *bv )
578{
579	struct berval	*new;
580
581	if ( (new = (struct berval *) malloc( sizeof(struct berval) ))
582	    == NULL ) {
583		return( NULL );
584	}
585	if ( (new->bv_val = (char *) malloc( bv->bv_len + 1 )) == NULL ) {
586		free(new);
587		return( NULL );
588	}
589	SAFEMEMCPY( new->bv_val, bv->bv_val, (size_t) bv->bv_len );
590	new->bv_val[bv->bv_len] = '\0';
591	new->bv_len = bv->bv_len;
592
593	return( new );
594}
595
596
597#ifdef STR_TRANSLATION
598void
599ber_set_string_translators( BerElement *ber, BERTranslateProc encode_proc,
600	BERTranslateProc decode_proc )
601{
602    ber->ber_encode_translate_proc = encode_proc;
603    ber->ber_decode_translate_proc = decode_proc;
604}
605#endif /* STR_TRANSLATION */
606
607int ber_flatten(BerElement *ber, struct berval **bvPtr)
608{
609	struct berval * bv;
610	int len;
611
612	if ((ber == NULL) || (ber->ber_buf == NULL))
613		return (-1);
614
615	len = ber->ber_ptr - ber->ber_buf;
616
617	if ((bv = (struct berval *)malloc(sizeof(struct berval))) == NULL)
618		return (-1);
619	if ((bv->bv_val = (char *) malloc(len + 1)) == NULL) {
620		free(bv);
621		return (-1);
622	}
623
624	SAFEMEMCPY(bv->bv_val, ber->ber_buf, (size_t)len);
625	bv->bv_val[len] = '\0';
626	bv->bv_len = len;
627
628	*bvPtr = bv;
629	return (0);
630}
631