Ejemplo n.º 1
0
static ber_slen_t
sb_debug_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	ber_slen_t		ret;
	char ebuf[128];

	ret = LBER_SBIOD_WRITE_NEXT( sbiod, buf, len );
	if (sbiod->sbiod_sb->sb_debug & LDAP_DEBUG_PACKETS) {
		int err = sock_errno();
		if ( ret < 0 ) {
			ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
				"%swrite: want=%ld error=%s\n",
				(char *)sbiod->sbiod_pvt, (long)len,
				AC_STRERROR_R( err, ebuf, sizeof ebuf ) );
		} else {
			ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
				"%swrite: want=%ld, written=%ld\n",
				(char *)sbiod->sbiod_pvt, (long)len, (long)ret );
			ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
				(const char *)buf, ret );
		}
		sock_errset(err);
	}

	return ret;
}
Ejemplo n.º 2
0
/*
 * Write to the ber buffer.
 * Note that ber_start_seqorset/ber_put_seqorset() bypass ber_write().
 */
ber_slen_t
ber_write(
	BerElement *ber,
	LDAP_CONST char *buf,
	ber_len_t len,
	int zero )	/* nonzero is unsupported from OpenLDAP 2.4.18 */
{
	char **p;

	assert( ber != NULL );
	assert( buf != NULL );
	assert( LBER_VALID( ber ) );

	if ( zero != 0 ) {
		ber_log_printf( LDAP_DEBUG_ANY, ber->ber_debug, "%s",
			"ber_write: nonzero 4th argument not supported\n" );
		return( -1 );
	}

	p = ber->ber_sos_ptr == NULL ? &ber->ber_ptr : &ber->ber_sos_ptr;
	if ( len > (ber_len_t) (ber->ber_end - *p) ) {
		if ( ber_realloc( ber, len ) != 0 ) return( -1 );
	}
	AC_MEMCPY( *p, buf, len );
	*p += len;

	return( (ber_slen_t) len );
}
Ejemplo n.º 3
0
static ber_len_t
sb_sasl_generic_pkt_length(
	struct sb_sasl_generic_data *p,
	const unsigned char *buf,
	int debuglevel )
{
	ber_len_t		size;

	assert( buf != NULL );

	size = buf[0] << 24
		| buf[1] << 16
		| buf[2] << 8
		| buf[3];

	if ( size > p->max_recv ) {
		/* somebody is trying to mess me up. */
		ber_log_printf( LDAP_DEBUG_ANY, debuglevel,
			"sb_sasl_generic_pkt_length: "
			"received illegal packet length of %lu bytes\n",
			(unsigned long)size );
		size = 16; /* this should lead to an error. */
	}

	return size + 4; /* include the size !!! */
}
Ejemplo n.º 4
0
static ber_slen_t
sb_debug_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	ber_slen_t		ret;

	ret = LBER_SBIOD_READ_NEXT( sbiod, buf, len );
	if (sbiod->sbiod_sb->sb_debug & LDAP_DEBUG_PACKETS)
	{
	    int err = errno;
	    if ( ret < 0 ) {
		ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
			"%sread: want=%ld error=%s\n", (char *)sbiod->sbiod_pvt,
			(long)len, STRERROR( errno ) );
	    } else {
		ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
			"%sread: want=%ld, got=%ld\n", (char *)sbiod->sbiod_pvt,
			(long)len, (long)ret );
		ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
			(const char *)buf, ret );
	    }
	    errno = err;
	}
	return ret;
}
Ejemplo n.º 5
0
int
ber_flush2( Sockbuf *sb, BerElement *ber, int freeit )
{
	ber_len_t	towrite;
	ber_slen_t	rc;

	assert( sb != NULL );
	assert( ber != NULL );

	assert( SOCKBUF_VALID( sb ) );
	assert( LBER_VALID( ber ) );

	if ( ber->ber_rwptr == NULL ) {
		ber->ber_rwptr = ber->ber_buf;
	}
	towrite = ber->ber_ptr - ber->ber_rwptr;

	if ( sb->sb_debug ) {
		ber_log_printf( LDAP_DEBUG_TRACE, sb->sb_debug,
			"ber_flush2: %ld bytes to sd %ld%s\n",
			towrite, (long) sb->sb_fd,
			ber->ber_rwptr != ber->ber_buf ?  " (re-flush)" : "" );
		ber_log_bprint( LDAP_DEBUG_BER, sb->sb_debug,
			ber->ber_rwptr, towrite );
	}

	while ( towrite > 0 ) {
#ifdef LBER_TRICKLE
		sleep(1);
		rc = ber_int_sb_write( sb, ber->ber_rwptr, 1 );
#else
		rc = ber_int_sb_write( sb, ber->ber_rwptr, towrite );
#endif
		if ( rc <= 0 ) {
			if ( freeit & LBER_FLUSH_FREE_ON_ERROR ) ber_free( ber, 1 );
			return -1;
		}
		towrite -= rc;
		ber->ber_rwptr += rc;
	} 

	if ( freeit & LBER_FLUSH_FREE_ON_SUCCESS ) ber_free( ber, 1 );

	return 0;
}
Ejemplo n.º 6
0
static ber_slen_t
sb_sasl_generic_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
	struct sb_sasl_generic_data	*p;
	int				ret;
	ber_len_t			len2;

	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

	p = (struct sb_sasl_generic_data *)sbiod->sbiod_pvt;

	/* Is there anything left in the buffer? */
	if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
		ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
		if ( ret < 0 ) return ret;

		/* Still have something left?? */
		if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
			sock_errset(EAGAIN);
			return -1;
		}
	}

	len2 = p->max_send - 100;	/* For safety margin */
	len2 = len > len2 ? len2 : len;

	/* If we're just retrying a partial write, tell the
	 * caller it's done. Let them call again if there's
	 * still more left to write.
	 */
	if ( p->flags & LDAP_PVT_SASL_PARTIAL_WRITE ) {
		p->flags ^= LDAP_PVT_SASL_PARTIAL_WRITE;
		return len2;
	}

	/* now encode the next packet. */
	p->ops->reset_buf( p, &p->buf_out );

	ret = p->ops->encode( p, buf, len2, &p->buf_out );

	if ( ret != 0 ) {
		ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
			"sb_sasl_generic_write: failed to encode packet\n" );
		sock_errset(EIO);
		return -1;
	}

	ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );

	if ( ret < 0 ) {
		/* error? */
		int err = sock_errno();
		/* caller can retry this */
		if ( err == EAGAIN || err == EWOULDBLOCK || err == EINTR )
			p->flags |= LDAP_PVT_SASL_PARTIAL_WRITE;
		return ret;
	} else if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
		/* partial write? pretend nothing got written */
		p->flags |= LDAP_PVT_SASL_PARTIAL_WRITE;
		sock_errset(EAGAIN);
		len2 = -1;
	}

	/* return number of bytes encoded, not written, to ensure
	 * no byte is encoded twice (even if only sent once).
	 */
	return len2;
}
Ejemplo n.º 7
0
static ber_slen_t
sb_sasl_generic_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
	struct sb_sasl_generic_data	*p;
	ber_slen_t			ret, bufptr;

	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

	p = (struct sb_sasl_generic_data *)sbiod->sbiod_pvt;

	/* Are there anything left in the buffer? */
	ret = ber_pvt_sb_copy_out( &p->buf_in, buf, len );
	bufptr = ret;
	len -= ret;

	if ( len == 0 )
		return bufptr;

	p->ops->reset_buf( p, &p->buf_in );

	/* Read the length of the packet */
	while ( p->sec_buf_in.buf_ptr < 4 ) {
		ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
			p->sec_buf_in.buf_ptr,
			4 - p->sec_buf_in.buf_ptr );
#ifdef EINTR
		if ( ( ret < 0 ) && ( errno == EINTR ) )
			continue;
#endif
		if ( ret <= 0 )
			return bufptr ? bufptr : ret;

		p->sec_buf_in.buf_ptr += ret;
	}

	/* The new packet always starts at p->sec_buf_in.buf_base */
	ret = sb_sasl_generic_pkt_length(p, (unsigned char *) p->sec_buf_in.buf_base,
		sbiod->sbiod_sb->sb_debug );

	/* Grow the packet buffer if neccessary */
	if ( ( p->sec_buf_in.buf_size < (ber_len_t) ret ) && 
		ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 )
	{
		sock_errset(ENOMEM);
		return -1;
	}
	p->sec_buf_in.buf_end = ret;

	/* Did we read the whole encrypted packet? */
	while ( p->sec_buf_in.buf_ptr < p->sec_buf_in.buf_end ) {
		/* No, we have got only a part of it */
		ret = p->sec_buf_in.buf_end - p->sec_buf_in.buf_ptr;

		ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base +
			p->sec_buf_in.buf_ptr, ret );
#ifdef EINTR
		if ( ( ret < 0 ) && ( errno == EINTR ) )
			continue;
#endif
		if ( ret <= 0 )
			return bufptr ? bufptr : ret;

		p->sec_buf_in.buf_ptr += ret;
   	}

	/* Decode the packet */
	ret = p->ops->decode( p, &p->sec_buf_in, &p->buf_in );

	/* Drop the packet from the input buffer */
	sb_sasl_generic_drop_packet( p, sbiod->sbiod_sb->sb_debug );

	if ( ret != 0 ) {
		ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
			"sb_sasl_generic_read: failed to decode packet\n" );
		sock_errset(EIO);
		return -1;
	}

	bufptr += ber_pvt_sb_copy_out( &p->buf_in, (char*) buf + bufptr, len );

	return bufptr;
}