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