X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Fliblber%2Fencode.c;h=741e269e3153758ee5a119b539495773134b9469;hb=0355abeb1a0ea471970c5313a69ce5b20916b408;hp=3003ddb3300357e97ec02f3fd45bd2eb0de1bd3a;hpb=942d37afc59f173df17412851bf52c4929535059;p=openldap diff --git a/libraries/liblber/encode.c b/libraries/liblber/encode.c index 3003ddb330..741e269e31 100644 --- a/libraries/liblber/encode.c +++ b/libraries/liblber/encode.c @@ -1,11 +1,19 @@ /* encode.c - ber output encoding routines */ /* $OpenLDAP$ */ -/* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2007 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ -/* Portions - * Copyright (c) 1990 Regents of the University of Michigan. +/* Portions Copyright (c) 1990 Regents of the University of Michigan. * All rights reserved. * * Redistribution and use in source and binary forms are permitted @@ -15,6 +23,10 @@ * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. */ +/* ACKNOWLEDGEMENTS: + * This work was originally developed by the University of Michigan + * (as part of U-MICH LDAP). + */ #include "portable.h" @@ -26,9 +38,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(( @@ -47,22 +56,23 @@ static int ber_put_int_or_enum LDAP_P(( ber_int_t num, ber_tag_t tag )); +#define BER_TOP_BYTE(type) (sizeof(type)-1) +#define BER_TOP_MASK(type) ((type)0xffU << (BER_TOP_BYTE(type)*8)) -static ber_len_t +static int ber_calc_taglen( ber_tag_t tag ) { - int i; - ber_tag_t mask; + int i = BER_TOP_BYTE(ber_tag_t); + ber_tag_t mask = BER_TOP_MASK(ber_tag_t); /* find the first non-all-zero byte in the tag */ - for ( i = sizeof(ber_tag_t) - 1; i > 0; i-- ) { - mask = ((ber_tag_t)0xffU << (i * 8)); + for ( ; i > 0; i-- ) { /* not all zero */ - if ( tag & mask ) - break; + if ( tag & mask ) break; + mask >>= 8; } - return( i + 1 ); + return i + 1; } static int @@ -72,23 +82,21 @@ ber_put_tag( int nosos ) { int rc; - ber_len_t taglen; - ber_len_t i; + int taglen; + int i; unsigned char nettag[sizeof(ber_tag_t)]; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); taglen = ber_calc_taglen( tag ); - for( i=0; i=0; i-- ) { + nettag[i] = (unsigned char)(tag & 0xffU); tag >>= 8; } - rc = ber_write( ber, - &nettag[sizeof(ber_tag_t) - taglen], - taglen, nosos ); + rc = ber_write( ber, (char *) nettag, taglen, nosos ); return rc; } @@ -101,22 +109,18 @@ ber_calc_lenlen( ber_len_t len ) * with bit 8 0. */ - if ( len <= (ber_len_t) 0x7FU ) - return( 1 ); + if ( len <= (ber_len_t) 0x7FU ) return 1; /* * long len otherwise - one byte with bit 8 set, giving the * length of the length, followed by the length itself. */ - if ( len <= (ber_len_t) 0xffU ) - return( 2 ); - if ( len <= (ber_len_t) 0xffffU ) - return( 3 ); - if ( len <= (ber_len_t) 0xffffffU ) - return( 4 ); + if ( len <= (ber_len_t) 0xffU ) return 2; + if ( len <= (ber_len_t) 0xffffU ) return 3; + if ( len <= (ber_len_t) 0xffffffU ) return 4; - return( 5 ); + return 5; } static int @@ -129,7 +133,7 @@ ber_put_len( BerElement *ber, ber_len_t len, int nosos ) unsigned char netlen[sizeof(ber_len_t)]; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); /* * short len if it's less than 128 - one byte giving the len, @@ -138,7 +142,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 ); } /* @@ -147,35 +151,93 @@ ber_put_len( BerElement *ber, ber_len_t len, int nosos ) */ /* find the first non-all-zero byte */ - for ( i = sizeof(ber_len_t) - 1; i > 0; i-- ) { - mask = ((ber_len_t)0xffU << (i * 8)); + i = BER_TOP_BYTE(ber_len_t); + mask = BER_TOP_MASK(ber_len_t); + for ( ; i > 0; i-- ) { /* not all zero */ - if ( len & mask ) - break; + if ( len & mask ) break; + mask >>= 8; } lenlen = (unsigned char) ++i; - if ( lenlen > 4 ) - return( -1 ); + if ( lenlen > 4 ) return -1; lenlen |= 0x80UL; /* write the length of the length */ - if ( ber_write( ber, &lenlen, 1, nosos ) != 1 ) - return( -1 ); + if ( ber_write( ber, &lenlen, 1, nosos ) != 1 ) return -1; - for( j=0; j=0; j-- ) { + netlen[j] = (unsigned char)(len & 0xffU); len >>= 8; } /* write the length itself */ - rc = ber_write( ber, - &netlen[sizeof(ber_len_t)-i], - i, nosos ); + rc = ber_write( ber, (char *) netlen, i, nosos ); return rc == i ? i+1 : -1; } +/* out->bv_len should be the buffer size on input */ +int +ber_encode_oid( BerValue *in, BerValue *out ) +{ + unsigned char *der = out->bv_val; + unsigned long val, val1; + int i, len; + char *ptr, *end, *inend; + + assert( in != NULL ); + assert( out != NULL ); + + if ( !out->bv_val || out->bv_len < in->bv_len ) + return -1; + + /* OIDs must have at least two components */ + if ( sscanf( in->bv_val, "%ld.%ld", &val, &val1 ) != 2 ) + return -1; + + val *= 40; + val += val1; + + inend = in->bv_val + in->bv_len; + + ptr = strchr( in->bv_val, '.' ); + ptr = strchr( ptr+1, '.' ); + if ( ptr ) + ++ptr; + else + ptr = inend; + + for (;;) { + if ( !val ) { + *der++ = 0; + } else { + int hibit = 0; + i = sizeof(unsigned long) + 1; + len = i; + for (;val;) { + i--; + val1 = val & 0x7f; + val >>= 7; + der[i] = val1 | hibit; + hibit = 0x80; + } + if ( i ) { + len -= i; + memcpy( der, der+i, len ); + } + der += len; + } + if ( ptr >= inend ) break; + val = strtol( ptr, &end, 10 ); + if ( ptr == end ) break; + if ( *end && *end != '.' ) break; + ptr = end + 1; + } + out->bv_len = (char *)der - out->bv_val; + return 0; +} + static int ber_put_int_or_enum( BerElement *ber, @@ -183,33 +245,32 @@ ber_put_int_or_enum( ber_tag_t tag ) { int rc; - int i, j, sign; - ber_len_t len, lenlen, taglen; + int i, j, sign, taglen, lenlen; + ber_len_t len; ber_uint_t unum, mask; unsigned char netnum[sizeof(ber_uint_t)]; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); sign = (num < 0); - unum = num; /* Bit fiddling should be done with unsigned values */ + unum = num; /* Bit fiddling should be done with unsigned values */ /* * high bit is set - look for first non-all-one byte * high bit is clear - look for first non-all-zero byte */ - for ( i = sizeof(ber_int_t) - 1; i > 0; i-- ) { - mask = ((ber_uint_t)0xffU << (i * 8)); - + i = BER_TOP_BYTE(ber_int_t); + mask = BER_TOP_MASK(ber_uint_t); + for ( ; i > 0; i-- ) { if ( sign ) { /* not all ones */ - if ( (unum & mask) != mask ) - break; + if ( (unum & mask) != mask ) break; } else { /* not all zero */ - if ( unum & mask ) - break; + if ( unum & mask ) break; } + mask >>= 8; } /* @@ -217,26 +278,27 @@ ber_put_int_or_enum( * byte matches the sign bit, we need to "back up" a byte. */ mask = (unum & ((ber_uint_t)0x80U << (i * 8))); - if ( (mask && !sign) || (sign && !mask) ) + if ( (mask && !sign) || (sign && !mask) ) { i++; + } len = i + 1; - if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) - return( -1 ); + if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) { + return -1; + } - if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 ) - return( -1 ); + if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 ) { + return -1; + } i++; - for( j=0; j=0; j-- ) { + netnum[j] = (unsigned char)(unum & 0xffU); unum >>= 8; } - rc = ber_write( ber, - &netnum[sizeof(ber_int_t) - i], - i, 0 ); + rc = ber_write( ber, (char *) netnum, i, 0 ); /* length of tag + length + contents */ return rc == i ? taglen + lenlen + i : -1; @@ -249,12 +311,13 @@ ber_put_enum( 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_ENUMERATED; + } - return( ber_put_int_or_enum( ber, num, tag ) ); + return ber_put_int_or_enum( ber, num, tag ); } int @@ -264,12 +327,13 @@ ber_put_int( 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_INTEGER; + } - return( ber_put_int_or_enum( ber, num, tag ) ); + return ber_put_int_or_enum( ber, num, tag ); } int @@ -279,60 +343,40 @@ ber_put_ostring( ber_len_t len, ber_tag_t tag ) { - ber_len_t taglen, lenlen; - int rc; -#ifdef STR_TRANSLATION - int free_str; -#endif /* STR_TRANSLATION */ + int taglen, lenlen, rc; assert( ber != NULL ); assert( str != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); - if ( tag == LBER_DEFAULT ) + if ( tag == LBER_DEFAULT ) { tag = LBER_OCTETSTRING; + } if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 ) - return( -1 ); - -#ifdef STR_TRANSLATION - if ( len > 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 ) { + (ber_len_t) ber_write( ber, str, len, 0 ) != len ) + { rc = -1; } else { /* return length of tag + length + contents */ rc = taglen + lenlen + len; } -#ifdef STR_TRANSLATION - if ( free_str ) { - LBER_FREE( str ); - } -#endif /* STR_TRANSLATION */ - - return( rc ); + return rc; } int ber_put_berval( BerElement *ber, - LDAP_CONST struct berval *bv, + struct berval *bv, 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 ); @@ -350,9 +394,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 @@ -362,53 +406,62 @@ ber_put_bitstring( ber_len_t blen /* in bits */, ber_tag_t tag ) { - ber_len_t taglen, lenlen, len; + int taglen, lenlen; + ber_len_t len; unsigned char unusedbits; 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 ber_put_null( BerElement *ber, ber_tag_t tag ) { - ber_len_t taglen; + int 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 @@ -417,27 +470,30 @@ ber_put_boolean( ber_int_t boolval, ber_tag_t tag ) { - ber_len_t taglen; - unsigned char trueval = 0xFFU; - unsigned char falseval = 0x00U; + int taglen; + unsigned char c; 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 ); + c = boolval ? (unsigned char) ~0U : (unsigned char) 0U; - if ( ber_write( ber, (char *)(boolval ? &trueval : &falseval), 1, 0 ) - != 1 ) - return( -1 ); + if ( ber_write( ber, (char *) &c, 1, 0 ) != 1 ) { + return -1; + } - return( taglen + 2 ); + return taglen + 2; } #define FOUR_BYTE_LEN 5 @@ -450,18 +506,20 @@ ber_start_seqorset( Seqorset *new; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); - new = (Seqorset *) LBER_CALLOC( 1, sizeof(Seqorset) ); + new = (Seqorset *) ber_memcalloc_x( 1, sizeof(Seqorset), ber->ber_memctx ); - 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; @@ -470,31 +528,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 @@ -503,17 +563,20 @@ ber_put_seqorset( BerElement *ber ) int rc; ber_len_t len; unsigned char netlen[sizeof(ber_len_t)]; - ber_len_t taglen, lenlen; + int taglen; + ber_len_t lenlen; unsigned char ltag = 0x80U + FOUR_BYTE_LEN - 1; Seqorset *next; Seqorset **sos = &ber->ber_sos; assert( ber != NULL ); - assert( BER_VALID( ber ) ); + assert( LBER_VALID( ber ) ); + + if( *sos == NULL ) return -1; /* * 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. @@ -521,8 +584,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 ); @@ -532,24 +596,27 @@ ber_put_seqorset( BerElement *ber ) } if( lenlen > 1 ) { - ber_len_t i; - for( i=0; i < lenlen-1; i++ ) { - netlen[(sizeof(ber_len_t)-1) - i] = - (unsigned char)((len >> i*8) & 0xffU); + int i; + ber_len_t j = len; + for( i=lenlen-2; i >= 0; i-- ) { + netlen[i] = j & 0xffU; + j >>= 8; } } else { - netlen[sizeof(ber_len_t)-1] = (unsigned char)(len & 0x7fU); + netlen[0] = (unsigned char)(len & 0x7fU); } if ( (next = (*sos)->sos_next) == NULL ) { /* write the tag */ - if ( (taglen = ber_put_tag( ber, (*sos)->sos_tag, 1 )) == -1 ) + if ( (taglen = ber_put_tag( ber, (*sos)->sos_tag, 1 )) == -1 ) { return( -1 ); + } 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) { /* @@ -557,44 +624,56 @@ 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, - &netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN-1)], - FOUR_BYTE_LEN-1, 1 ); + rc = ber_write( ber, (char *) netlen, 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 */ (*sos)->sos_ber->ber_ptr += len; } else { - ber_len_t i; + int i; 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 ); - for( i = 0; i < taglen; i++ ) { - nettag[(sizeof(ber_tag_t)-1) - i] = (unsigned char)(tmptag & 0xffU); + for( i = taglen-1; i >= 0; i-- ) { + nettag[i] = (unsigned char)(tmptag & 0xffU); tmptag >>= 8; } - SAFEMEMCPY( (*sos)->sos_first, - &nettag[sizeof(ber_tag_t) - taglen], - taglen ); + AC_FMEMCPY( (*sos)->sos_first, nettag, taglen ); if ( ber->ber_options & LBER_USE_DER ) { ltag = (lenlen == 1) @@ -603,14 +682,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, - &netlen[sizeof(ber_len_t) - (lenlen - 1)], - lenlen - 1 ); + AC_FMEMCPY( (*sos)->sos_first + 2, netlen, lenlen - 1 ); } if (lenlen != FOUR_BYTE_LEN) { /* @@ -618,15 +695,14 @@ 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, - &netlen[sizeof(ber_len_t) - (FOUR_BYTE_LEN - 1)], - FOUR_BYTE_LEN - 1 ); + AC_FMEMCPY( (*sos)->sos_first + taglen + 1, + netlen, FOUR_BYTE_LEN - 1 ); } next->sos_clen += (taglen + lenlen + len); @@ -634,30 +710,33 @@ ber_put_seqorset( BerElement *ber ) } /* we're done with this seqorset, so free it up */ - LBER_FREE( (char *) (*sos) ); + ber_memfree_x( (char *) (*sos), ber->ber_memctx ); *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, ... ) @@ -672,7 +751,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 ); @@ -707,6 +786,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 ); @@ -756,6 +844,16 @@ ber_printf( BerElement *ber, LDAP_CONST char *fmt, ... ) } break; + case 'W': /* BerVarray */ + if ( (bv = va_arg( ap, BerVarray )) == NULL ) + break; + for ( i = 0; bv[i].bv_val != NULL; i++ ) { + if ( (rc = ber_put_berval( ber, &bv[i], + ber->ber_tag )) == -1 ) + break; + } + break; + case '{': /* begin sequence */ rc = ber_start_seq( ber, ber->ber_tag ); break; @@ -781,13 +879,14 @@ ber_printf( BerElement *ber, LDAP_CONST char *fmt, ... ) break; } - if ( ber->ber_usertag == 0 ) + if ( ber->ber_usertag == 0 ) { ber->ber_tag = LBER_DEFAULT; - else + } else { ber->ber_usertag = 0; + } } va_end( ap ); - return( rc ); + return rc; }