X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fcyrus.c;h=5310903c0ea570f59d59c2395ab7139e8bf6399f;hb=3b9f4a82ee478c943a66696adf9133dc9f503e16;hp=3674c44253fad5d0f6b46059952d25b78434c090;hpb=b315d8af349c00e8f7e1848e1b582dbaf0944c8e;p=openldap diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c index 3674c44253..5310903c0e 100644 --- a/libraries/libldap/cyrus.c +++ b/libraries/libldap/cyrus.c @@ -23,7 +23,11 @@ ldap_pvt_thread_mutex_t ldap_int_sasl_mutex; #endif +#ifdef HAVE_SASL_SASL_H +#include +#else #include +#endif #if SASL_VERSION_MAJOR >= 2 #define SASL_CONST const @@ -88,6 +92,7 @@ int ldap_int_sasl_init( void ) struct sb_sasl_data { sasl_conn_t *sasl_context; + unsigned *sasl_maxbuf; Sockbuf_Buf sec_buf_in; Sockbuf_Buf buf_in; Sockbuf_Buf buf_out; @@ -108,9 +113,12 @@ sb_sasl_setup( Sockbuf_IO_Desc *sbiod, void *arg ) ber_pvt_sb_buf_init( &p->buf_in ); ber_pvt_sb_buf_init( &p->buf_out ); if ( ber_pvt_sb_grow_buffer( &p->sec_buf_in, SASL_MIN_BUFF_SIZE ) < 0 ) { + LBER_FREE( p ); errno = ENOMEM; return -1; } + sasl_getprop( p->sasl_context, SASL_MAXOUTBUF, + (SASL_CONST void **) &p->sasl_maxbuf ); sbiod->sbiod_pvt = p; @@ -142,7 +150,7 @@ sb_sasl_remove( Sockbuf_IO_Desc *sbiod ) } static ber_len_t -sb_sasl_pkt_length( const unsigned char *buf, int debuglevel ) +sb_sasl_pkt_length( const unsigned char *buf, unsigned max, int debuglevel ) { ber_len_t size; @@ -153,15 +161,16 @@ sb_sasl_pkt_length( const unsigned char *buf, int debuglevel ) | buf[2] << 8 | buf[3]; - /* we really should check against actual buffer size set - * in the secopts. - */ if ( size > SASL_MAX_BUFF_SIZE ) { /* somebody is trying to mess me up. */ ber_log_printf( LDAP_DEBUG_ANY, debuglevel, "sb_sasl_pkt_length: received illegal packet length " "of %lu bytes\n", (unsigned long)size ); size = 16; /* this should lead to an error. */ + } else if ( size > max ) { + ber_log_printf( LDAP_DEBUG_ANY, debuglevel, + "sb_sasl_pkt_length: received packet length " + "of %lu exceeds negotiated max of %lu bytes\n", (unsigned long)size, (unsigned long)max ); } return size + 4; /* include the size !!! */ @@ -169,7 +178,7 @@ sb_sasl_pkt_length( const unsigned char *buf, int debuglevel ) /* Drop a processed packet from the input buffer */ static void -sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, int debuglevel ) +sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, unsigned max, int debuglevel ) { ber_slen_t len; @@ -180,7 +189,7 @@ sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, int debuglevel ) if ( len >= 4 ) { sec_buf_in->buf_end = sb_sasl_pkt_length( sec_buf_in->buf_base, - debuglevel); + max, debuglevel); } else { sec_buf_in->buf_end = 0; @@ -229,7 +238,7 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) /* The new packet always starts at p->sec_buf_in.buf_base */ ret = sb_sasl_pkt_length( p->sec_buf_in.buf_base, - sbiod->sbiod_sb->sb_debug ); + *p->sasl_maxbuf, sbiod->sbiod_sb->sb_debug ); /* Grow the packet buffer if neccessary */ if ( ( p->sec_buf_in.buf_size < (ber_len_t) ret ) && @@ -262,19 +271,19 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) p->sec_buf_in.buf_end, (SASL_CONST char **)&p->buf_in.buf_base, (unsigned *)&p->buf_in.buf_end ); + + /* Drop the packet from the input buffer */ + sb_sasl_drop_packet( &p->sec_buf_in, + *p->sasl_maxbuf, sbiod->sbiod_sb->sb_debug ); + if ( ret != SASL_OK ) { ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug, "sb_sasl_read: failed to decode packet: %s\n", sasl_errstring( ret, NULL, NULL ) ); - sb_sasl_drop_packet( &p->sec_buf_in, - sbiod->sbiod_sb->sb_debug ); errno = EIO; return -1; } - /* Drop the packet from the input buffer */ - sb_sasl_drop_packet( &p->sec_buf_in, sbiod->sbiod_sb->sb_debug ); - p->buf_in.buf_size = p->buf_in.buf_end; bufptr += ber_pvt_sb_copy_out( &p->buf_in, (char*) buf + bufptr, len ); @@ -306,6 +315,8 @@ sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) #else ber_pvt_sb_buf_destroy( &p->buf_out ); #endif + if ( len > *p->sasl_maxbuf - 100 ) + len = *p->sasl_maxbuf - 100; /* For safety margin */ ret = sasl_encode( p->sasl_context, buf, len, (SASL_CONST char **)&p->buf_out.buf_base, (unsigned *)&p->buf_out.buf_size ); @@ -349,8 +360,12 @@ Sockbuf_IO ldap_pvt_sockbuf_io_sasl = { int ldap_pvt_sasl_install( Sockbuf *sb, void *ctx_arg ) { +#ifdef NEW_LOGGING + LDAP_LOG ( TRANSPORT, ENTRY, "ldap_pvt_sasl_install\n", 0, 0, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "ldap_pvt_sasl_install\n", 0, 0, 0 ); +#endif /* don't install the stuff unless security has been negotiated */ @@ -421,19 +436,6 @@ ldap_int_sasl_open( int rc; sasl_conn_t *ctx; - sasl_callback_t *session_callbacks = - LDAP_CALLOC( 2, sizeof( sasl_callback_t ) ); - - if( session_callbacks == NULL ) return LDAP_NO_MEMORY; - - session_callbacks[0].id = SASL_CB_USER; - session_callbacks[0].proc = NULL; - session_callbacks[0].context = ld; - - session_callbacks[1].id = SASL_CB_LIST_END; - session_callbacks[1].proc = NULL; - session_callbacks[1].context = NULL; - assert( lc->lconn_sasl_ctx == NULL ); if ( host == NULL ) { @@ -443,20 +445,24 @@ ldap_int_sasl_open( #if SASL_VERSION_MAJOR >= 2 rc = sasl_client_new( "ldap", host, NULL, NULL, - session_callbacks, 0, &ctx ); + NULL, 0, &ctx ); #else - rc = sasl_client_new( "ldap", host, session_callbacks, + rc = sasl_client_new( "ldap", host, NULL, SASL_SECURITY_LAYER, &ctx ); #endif - LDAP_FREE( session_callbacks ); if ( rc != SASL_OK ) { ld->ld_errno = sasl_err2ldap( rc ); return ld->ld_errno; } +#ifdef NEW_LOGGING + LDAP_LOG ( TRANSPORT, DETAIL1, "ldap_int_sasl_open: host=%s\n", + host, 0, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: host=%s\n", host, 0, 0 ); +#endif lc->lconn_sasl_ctx = ctx; @@ -472,8 +478,13 @@ ldap_int_sasl_open( (void) sasl_setprop( ctx, SASL_SSF_EXTERNAL, (void *) &extprops ); #endif +#ifdef NEW_LOGGING + LDAP_LOG ( TRANSPORT, DETAIL1, + "ldap_int_sasl_open: ssf=%ld\n", (long) ssf, 0, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_open: ssf=%ld\n", (long) ssf, 0, 0 ); +#endif } return LDAP_SUCCESS; @@ -513,8 +524,13 @@ ldap_int_sasl_bind( struct berval ccred; ber_socket_t sd; +#ifdef NEW_LOGGING + LDAP_LOG ( TRANSPORT, ARGS, "ldap_int_sasl_bind: %s\n", + mechs ? mechs : "", 0, 0 ); +#else Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: %s\n", mechs ? mechs : "", 0, 0 ); +#endif /* do a quick !LDAPv3 check... ldap_sasl_bind will do the rest. */ if (ld->ld_version < LDAP_VERSION3) { @@ -596,6 +612,9 @@ ldap_int_sasl_bind( if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) { ld->ld_errno = sasl_err2ldap( saslrc ); +#if SASL_VERSION_MAJOR >= 2 + ld->ld_error = (char *)sasl_errdetail( ctx ); +#endif return ld->ld_errno; } @@ -617,9 +636,15 @@ ldap_int_sasl_bind( if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) { if( scred && scred->bv_len ) { /* and server provided us with data? */ +#ifdef NEW_LOGGING + LDAP_LOG ( TRANSPORT, DETAIL1, + "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n", + rc, saslrc, scred->bv_len ); +#else Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n", rc, saslrc, scred->bv_len ); +#endif ber_bvfree( scred ); } return ld->ld_errno; @@ -629,9 +654,15 @@ ldap_int_sasl_bind( /* we're done, no need to step */ if( scred && scred->bv_len ) { /* but server provided us with data! */ +#ifdef NEW_LOGGING + LDAP_LOG ( TRANSPORT, DETAIL1, + "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n", + rc, saslrc, scred->bv_len ); +#else Debug( LDAP_DEBUG_TRACE, "ldap_int_sasl_bind: rc=%d sasl=%d len=%ld\n", rc, saslrc, scred->bv_len ); +#endif ber_bvfree( scred ); return ld->ld_errno = LDAP_LOCAL_ERROR; } @@ -646,8 +677,13 @@ ldap_int_sasl_bind( (SASL_CONST char **)&ccred.bv_val, &credlen ); - Debug( LDAP_DEBUG_TRACE, "sasl_client_start: %d\n", +#ifdef NEW_LOGGING + LDAP_LOG ( TRANSPORT, DETAIL1, + "ldap_int_sasl_bind: sasl_client_step: %d\n", saslrc,0,0 ); +#else + Debug( LDAP_DEBUG_TRACE, "sasl_client_step: %d\n", saslrc, 0, 0 ); +#endif #if SASL_VERSION_MAJOR >= 2 /* XXX the application should free interact results. */ @@ -672,6 +708,9 @@ ldap_int_sasl_bind( if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) { ld->ld_errno = sasl_err2ldap( saslrc ); +#if SASL_VERSION_MAJOR >= 2 + ld->ld_error = (char *)sasl_errdetail( ctx ); +#endif return ld->ld_errno; } } while ( rc == LDAP_SASL_BIND_IN_PROGRESS ); @@ -681,6 +720,9 @@ ldap_int_sasl_bind( } if ( saslrc != SASL_OK ) { +#if SASL_VERSION_MAJOR >= 2 + ld->ld_error = (char *)sasl_errdetail( ctx ); +#endif return ld->ld_errno = sasl_err2ldap( saslrc ); } @@ -739,6 +781,8 @@ ldap_int_sasl_external( #if SASL_VERSION_MAJOR >= 2 sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL, &ssf ); + if ( sc == SASL_OK ) + sc = sasl_setprop( ctx, SASL_AUTH_EXTERNAL, authid ); #else memset( &extprops, '\0', sizeof(extprops) ); extprops.ssf = ssf; @@ -806,7 +850,7 @@ int ldap_pvt_sasl_secprops( } else if( !strncasecmp(props[i], "minssf=", sizeof("minssf")) ) { - if( isdigit( props[i][sizeof("minssf")] ) ) { + if( isdigit( (unsigned char) props[i][sizeof("minssf")] ) ) { got_min_ssf++; min_ssf = atoi( &props[i][sizeof("minssf")] ); } else { @@ -816,7 +860,7 @@ int ldap_pvt_sasl_secprops( } else if( !strncasecmp(props[i], "maxssf=", sizeof("maxssf")) ) { - if( isdigit( props[i][sizeof("maxssf")] ) ) { + if( isdigit( (unsigned char) props[i][sizeof("maxssf")] ) ) { got_max_ssf++; max_ssf = atoi( &props[i][sizeof("maxssf")] ); } else { @@ -826,7 +870,7 @@ int ldap_pvt_sasl_secprops( } else if( !strncasecmp(props[i], "maxbufsize=", sizeof("maxbufsize")) ) { - if( isdigit( props[i][sizeof("maxbufsize")] ) ) { + if( isdigit( (unsigned char) props[i][sizeof("maxbufsize")] ) ) { got_maxbufsize++; maxbufsize = atoi( &props[i][sizeof("maxbufsize")] ); } else {