X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Fliblber%2Fencode.c;h=08fc871e5be22361c7ed0c4cfb4d9db5e3a93721;hb=b917625a851a35e16cb4b654e6e33de0c5faf268;hp=8a624f74ad03c57c7c5f849a5785d8bbaa116930;hpb=482b1d7152f0c5c86156821074a22fb8118a70f0;p=openldap diff --git a/libraries/liblber/encode.c b/libraries/liblber/encode.c index 8a624f74ad..08fc871e5b 100644 --- a/libraries/liblber/encode.c +++ b/libraries/liblber/encode.c @@ -1,7 +1,7 @@ -/* encode.c - ber output encoding routines */ +/* Encode.c - ber output encoding routines */ /* $OpenLDAP$ */ /* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* Portions @@ -26,9 +26,6 @@ #include #include -#undef LDAP_F_PRE -#define LDAP_F_PRE LDAP_F_EXPORT - #include "lber-int.h" static int ber_put_len LDAP_P(( @@ -58,11 +55,10 @@ ber_calc_taglen( ber_tag_t tag ) for ( i = sizeof(ber_tag_t) - 1; i > 0; i-- ) { mask = ((ber_tag_t)0xffU << (i * 8)); /* not all zero */ - if ( tag & mask ) - break; + if ( tag & mask ) break; } - return( i + 1 ); + return i + 1; } static int @@ -75,10 +71,9 @@ ber_put_tag( ber_len_t taglen; ber_len_t i; unsigned char nettag[sizeof(ber_tag_t)]; - ber_tag_t xtag; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); taglen = ber_calc_taglen( tag ); @@ -103,7 +98,7 @@ ber_calc_lenlen( ber_len_t len ) */ if ( len <= (ber_len_t) 0x7FU ) - return( 1 ); + return 1; /* * long len otherwise - one byte with bit 8 set, giving the @@ -111,13 +106,13 @@ ber_calc_lenlen( ber_len_t len ) */ if ( len <= (ber_len_t) 0xffU ) - return( 2 ); + return 2; if ( len <= (ber_len_t) 0xffffU ) - return( 3 ); + return 3; if ( len <= (ber_len_t) 0xffffffU ) - return( 4 ); + return 4; - return( 5 ); + return 5; } static int @@ -128,10 +123,9 @@ ber_put_len( BerElement *ber, ber_len_t len, int nosos ) char lenlen; ber_len_t mask; unsigned char netlen[sizeof(ber_len_t)]; - ber_len_t xlen; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); /* * short len if it's less than 128 - one byte giving the len, @@ -140,7 +134,7 @@ ber_put_len( BerElement *ber, ber_len_t len, int nosos ) if ( len <= 127 ) { char length_byte = (char) len; - return( ber_write( ber, &length_byte, 1, nosos ) ); + return ber_write( ber, &length_byte, 1, nosos ); } /* @@ -152,18 +146,17 @@ ber_put_len( BerElement *ber, ber_len_t len, int nosos ) for ( i = sizeof(ber_len_t) - 1; i > 0; i-- ) { mask = ((ber_len_t)0xffU << (i * 8)); /* not all zero */ - if ( len & mask ) - break; + if ( len & mask ) break; } lenlen = (unsigned char) ++i; if ( lenlen > 4 ) - return( -1 ); + return -1; lenlen |= 0x80UL; /* write the length of the length */ if ( ber_write( ber, &lenlen, 1, nosos ) != 1 ) - return( -1 ); + return -1; for( j=0; j 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0 && - ber->ber_encode_translate_proc ) { - if ( (*(ber->ber_encode_translate_proc))( &str, &len, 0 ) - != 0 ) { - return( -1 ); - } - free_str = 1; - } else { - free_str = 0; - } -#endif /* STR_TRANSLATION */ + return -1; if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 || (ber_len_t) ber_write( ber, str, len, 0 ) != len ) { @@ -319,13 +299,7 @@ ber_put_ostring( rc = taglen + lenlen + len; } -#ifdef STR_TRANSLATION - if ( free_str ) { - LBER_FREE( str ); - } -#endif /* STR_TRANSLATION */ - - return( rc ); + return rc; } int @@ -335,7 +309,7 @@ ber_put_berval( ber_tag_t tag ) { assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); if( bv == NULL || bv->bv_len == 0 ) { return ber_put_ostring( ber, "", (ber_len_t) 0, tag ); @@ -353,9 +327,9 @@ ber_put_string( assert( ber != NULL ); assert( str != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); - return( ber_put_ostring( ber, str, strlen( str ), tag )); + return ber_put_ostring( ber, str, strlen( str ), tag ); } int @@ -371,27 +345,32 @@ ber_put_bitstring( assert( ber != NULL ); assert( str != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); - if ( tag == LBER_DEFAULT ) + if ( tag == LBER_DEFAULT ) { tag = LBER_BITSTRING; + } - if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) - return( -1 ); + if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) { + return -1; + } len = ( blen + 7 ) / 8; unusedbits = (unsigned char) ((len * 8) - blen); - if ( (lenlen = ber_put_len( ber, len + 1, 0 )) == -1 ) - return( -1 ); + if ( (lenlen = ber_put_len( ber, len + 1, 0 )) == -1 ) { + return -1; + } - if ( ber_write( ber, (char *)&unusedbits, 1, 0 ) != 1 ) - return( -1 ); + if ( ber_write( ber, (char *)&unusedbits, 1, 0 ) != 1 ) { + return -1; + } - if ( (ber_len_t) ber_write( ber, str, len, 0 ) != len ) - return( -1 ); + if ( (ber_len_t) ber_write( ber, str, len, 0 ) != len ) { + return -1; + } /* return length of tag + length + unused bit count + contents */ - return( taglen + 1 + lenlen + len ); + return taglen + 1 + lenlen + len; } int @@ -400,18 +379,21 @@ ber_put_null( BerElement *ber, ber_tag_t tag ) ber_len_t taglen; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); - if ( tag == LBER_DEFAULT ) + if ( tag == LBER_DEFAULT ) { tag = LBER_NULL; + } - if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) - return( -1 ); + if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) { + return -1; + } - if ( ber_put_len( ber, 0, 0 ) != 1 ) - return( -1 ); + if ( ber_put_len( ber, 0, 0 ) != 1 ) { + return -1; + } - return( taglen + 1 ); + return taglen + 1; } int @@ -421,26 +403,30 @@ ber_put_boolean( ber_tag_t tag ) { ber_len_t taglen; - unsigned char trueval = 0xFFU; - unsigned char falseval = 0x00U; + unsigned char trueval = (unsigned char) -1; + unsigned char falseval = 0; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); if ( tag == LBER_DEFAULT ) tag = LBER_BOOLEAN; - if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) - return( -1 ); + if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) { + return -1; + } - if ( ber_put_len( ber, 1, 0 ) != 1 ) - return( -1 ); + if ( ber_put_len( ber, 1, 0 ) != 1 ) { + return -1; + } if ( ber_write( ber, (char *)(boolval ? &trueval : &falseval), 1, 0 ) - != 1 ) - return( -1 ); + != 1 ) + { + return -1; + } - return( taglen + 2 ); + return taglen + 2; } #define FOUR_BYTE_LEN 5 @@ -453,18 +439,20 @@ ber_start_seqorset( Seqorset *new; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); new = (Seqorset *) LBER_CALLOC( 1, sizeof(Seqorset) ); - if ( new == NULL ) - return( -1 ); + if ( new == NULL ) { + return -1; + } new->sos_ber = ber; - if ( ber->ber_sos == NULL ) + if ( ber->ber_sos == NULL ) { new->sos_first = ber->ber_ptr; - else + } else { new->sos_first = ber->ber_sos->sos_ptr; + } /* Set aside room for a 4 byte length field */ new->sos_ptr = new->sos_first + ber_calc_taglen( tag ) + FOUR_BYTE_LEN; @@ -473,31 +461,33 @@ ber_start_seqorset( new->sos_next = ber->ber_sos; ber->ber_sos = new; - return( 0 ); + return 0; } int ber_start_seq( BerElement *ber, ber_tag_t tag ) { assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); - if ( tag == LBER_DEFAULT ) + if ( tag == LBER_DEFAULT ) { tag = LBER_SEQUENCE; + } - return( ber_start_seqorset( ber, tag ) ); + return ber_start_seqorset( ber, tag ); } int ber_start_set( BerElement *ber, ber_tag_t tag ) { assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); - if ( tag == LBER_DEFAULT ) + if ( tag == LBER_DEFAULT ) { tag = LBER_SET; + } - return( ber_start_seqorset( ber, tag ) ); + return ber_start_seqorset( ber, tag ); } static int @@ -512,11 +502,11 @@ ber_put_seqorset( BerElement *ber ) Seqorset **sos = &ber->ber_sos; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); /* * If this is the toplevel sequence or set, we need to actually - * write the stuff out. Otherwise, it's already been put in + * write the stuff out. Otherwise, it's already been put in * the appropriate buffer and will be written when the toplevel * one is written. In this case all we need to do is update the * length and tag. @@ -524,8 +514,9 @@ ber_put_seqorset( BerElement *ber ) len = (*sos)->sos_clen; - if ( sizeof(ber_len_t) > 4 && len > 0xffffffffUL ) - return( -1 ); + if ( sizeof(ber_len_t) > 4 && len > 0xffffffffUL ) { + return -1; + } if ( ber->ber_options & LBER_USE_DER ) { lenlen = ber_calc_lenlen( len ); @@ -551,8 +542,9 @@ ber_put_seqorset( BerElement *ber ) if ( ber->ber_options & LBER_USE_DER ) { /* Write the length in the minimum # of octets */ - if ( ber_put_len( ber, len, 1 ) == -1 ) - return( -1 ); + if ( ber_put_len( ber, len, 1 ) == -1 ) { + return -1; + } if (lenlen != FOUR_BYTE_LEN) { /* @@ -560,15 +552,16 @@ ber_put_seqorset( BerElement *ber ) * the length field. Move the data if * we don't actually need that much */ - SAFEMEMCPY( (*sos)->sos_first + taglen + + AC_MEMCPY( (*sos)->sos_first + taglen + lenlen, (*sos)->sos_first + taglen + FOUR_BYTE_LEN, len ); } } else { /* Fill FOUR_BYTE_LEN bytes for length field */ /* one byte of length length */ - if ( ber_write( ber, (char *)<ag, 1, 1 ) != 1 ) - return( -1 ); + if ( ber_write( ber, (char *)<ag, 1, 1 ) != 1 ) { + return -1; + } /* the length itself */ rc = ber_write( ber, @@ -576,7 +569,7 @@ ber_put_seqorset( BerElement *ber ) FOUR_BYTE_LEN-1, 1 ); if( rc != FOUR_BYTE_LEN - 1 ) { - return( -1 ); + return -1; } } /* The ber_ptr is at the set/seq start - move it to the end */ @@ -587,6 +580,21 @@ ber_put_seqorset( BerElement *ber ) unsigned char nettag[sizeof(ber_tag_t)]; ber_tag_t tmptag = (*sos)->sos_tag; + if( ber->ber_sos->sos_ptr > ber->ber_end ) { + /* The sos_ptr exceeds the end of the BerElement + * this can happen, for example, when the sos_ptr + * is near the end and no data was written for the + * 'V'. We must realloc the BerElement to ensure + * we don't overwrite the buffer when writing + * the tag and length fields. + */ + ber_len_t ext = ber->ber_sos->sos_ptr - ber->ber_end; + + if( ber_realloc( ber, ext ) != 0 ) { + return -1; + } + } + /* the tag */ taglen = ber_calc_taglen( tmptag ); @@ -595,7 +603,7 @@ ber_put_seqorset( BerElement *ber ) tmptag >>= 8; } - SAFEMEMCPY( (*sos)->sos_first, + AC_FMEMCPY( (*sos)->sos_first, &nettag[sizeof(ber_tag_t) - taglen], taglen ); @@ -606,12 +614,12 @@ ber_put_seqorset( BerElement *ber ) } /* one byte of length length */ - SAFEMEMCPY( (*sos)->sos_first + 1, <ag, 1 ); + (*sos)->sos_first[1] = ltag; if ( ber->ber_options & LBER_USE_DER ) { if (lenlen > 1) { /* Write the length itself */ - SAFEMEMCPY( (*sos)->sos_first + 2, + AC_FMEMCPY( (*sos)->sos_first + 2, &netlen[sizeof(ber_len_t) - (lenlen - 1)], lenlen - 1 ); } @@ -621,13 +629,13 @@ ber_put_seqorset( BerElement *ber ) * the length field. Move the data if * we don't actually need that much */ - SAFEMEMCPY( (*sos)->sos_first + taglen + + AC_FMEMCPY( (*sos)->sos_first + taglen + lenlen, (*sos)->sos_first + taglen + FOUR_BYTE_LEN, len ); } } else { /* the length itself */ - SAFEMEMCPY( (*sos)->sos_first + taglen + 1, + AC_FMEMCPY( (*sos)->sos_first + taglen + 1, &netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN - 1)], FOUR_BYTE_LEN - 1 ); } @@ -640,27 +648,30 @@ ber_put_seqorset( BerElement *ber ) LBER_FREE( (char *) (*sos) ); *sos = next; - return( taglen + lenlen + len ); + return taglen + lenlen + len; } int ber_put_seq( BerElement *ber ) { assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); - return( ber_put_seqorset( ber ) ); + return ber_put_seqorset( ber ); } int ber_put_set( BerElement *ber ) { assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); - return( ber_put_seqorset( ber ) ); + return ber_put_seqorset( ber ); } +/* N tag */ +static ber_tag_t lber_int_null = 0; + /* VARARGS */ int ber_printf( BerElement *ber, LDAP_CONST char *fmt, ... ) @@ -675,7 +686,7 @@ ber_printf( BerElement *ber, LDAP_CONST char *fmt, ... ) assert( ber != NULL ); assert( fmt != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); va_start( ap, fmt ); @@ -710,6 +721,15 @@ ber_printf( BerElement *ber, LDAP_CONST char *fmt, ... ) rc = ber_put_null( ber, ber->ber_tag ); break; + case 'N': /* Debug NULL */ + if( lber_int_null != 0 ) { + /* Insert NULL to ensure peer ignores unknown tags */ + rc = ber_put_null( ber, lber_int_null ); + } else { + rc = 0; + } + break; + case 'o': /* octet string (non-null terminated) */ s = va_arg( ap, char * ); len = va_arg( ap, ber_len_t ); @@ -777,8 +797,13 @@ ber_printf( BerElement *ber, LDAP_CONST char *fmt, ... ) default: if( ber->ber_debug ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "liblber", LDAP_LEVEL_ERR, + "ber_printf: unknown fmt %c\n", *fmt )); +#else ber_log_printf( LDAP_DEBUG_ANY, ber->ber_debug, "ber_printf: unknown fmt %c\n", *fmt ); +#endif } rc = -1; break; @@ -792,5 +817,5 @@ ber_printf( BerElement *ber, LDAP_CONST char *fmt, ... ) va_end( ap ); - return( rc ); + return rc; }