2014-11-19 08:37 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)

* contrib/hbnetio/netiosrv.c
    * small simplification

  * src/rtl/hbznet.c
    ! fixed possible data stream corruption which could be exploited in
      systems which can accept only one byte in socket write operation
      when internal TCP output buffers are full. Rather seldom situation
      but theoretically possible, i.e. in VPN.
This commit is contained in:
Przemysław Czerpak
2014-11-19 08:37:16 +01:00
parent 41ddee0ea9
commit ed3dd0415f
3 changed files with 48 additions and 44 deletions

View File

@@ -10,6 +10,16 @@
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
*/
2014-11-19 08:37 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* contrib/hbnetio/netiosrv.c
* small simplification
* src/rtl/hbznet.c
! fixed possible data stream corruption which could be exploited in
systems which can accept only one byte in socket write operation
when internal TCP output buffers are full. Rather seldom situation
but theoretically possible, i.e. in VPN.
2014-11-18 14:13 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* include/dbinfo.ch
+ added new rddInfo() action: RDDI_DECIMALS

View File

@@ -356,7 +356,7 @@ static PHB_CONSRV s_consrvNew( HB_SOCKET connsd, const char * szRootPath, HB_BOO
return conn;
}
static long s_srvRecvAll( PHB_CONSRV conn, void * buffer, long len )
static HB_BOOL s_srvRecvAll( PHB_CONSRV conn, void * buffer, long len )
{
HB_BYTE * ptr = ( HB_BYTE * ) buffer;
long lRead = 0, l;
@@ -385,10 +385,10 @@ static long s_srvRecvAll( PHB_CONSRV conn, void * buffer, long len )
}
}
return lRead;
return lRead == len;
}
static long s_srvSendAll( PHB_CONSRV conn, void * buffer, long len )
static HB_BOOL s_srvSendAll( PHB_CONSRV conn, void * buffer, long len )
{
HB_BYTE * ptr = ( HB_BYTE * ) buffer;
long lSent = 0, lLast = 1, l;
@@ -427,7 +427,7 @@ static long s_srvSendAll( PHB_CONSRV conn, void * buffer, long len )
if( conn->mutex )
hb_threadMutexUnlock( conn->mutex );
}
return lSent;
return lSent == len;
}
static HB_GARBAGE_FUNC( s_listensd_destructor )
@@ -726,21 +726,21 @@ static HB_BOOL s_netio_login_accept( PHB_CONSRV conn )
{
HB_BYTE msgbuf[ NETIO_MSGLEN ];
if( s_srvRecvAll( conn, msgbuf, NETIO_MSGLEN ) == NETIO_MSGLEN &&
if( s_srvRecvAll( conn, msgbuf, NETIO_MSGLEN ) &&
HB_GET_LE_INT32( msgbuf ) == NETIO_LOGIN )
{
long len = HB_GET_LE_INT16( &msgbuf[ 4 ] );
if( len < ( long ) sizeof( msgbuf ) &&
len == ( long ) strlen( NETIO_LOGINSTRID ) &&
s_srvRecvAll( conn, msgbuf, len ) == len )
s_srvRecvAll( conn, msgbuf, len ) )
{
if( memcmp( NETIO_LOGINSTRID, msgbuf, len ) == 0 )
{
HB_PUT_LE_UINT32( &msgbuf[ 0 ], NETIO_LOGIN );
HB_PUT_LE_UINT32( &msgbuf[ 4 ], NETIO_CONNECTED );
memset( msgbuf + 8, '\0', NETIO_MSGLEN - 8 );
if( s_srvSendAll( conn, msgbuf, NETIO_MSGLEN ) == NETIO_MSGLEN )
if( s_srvSendAll( conn, msgbuf, NETIO_MSGLEN ) )
conn->login = HB_TRUE;
}
}
@@ -792,7 +792,7 @@ HB_FUNC( NETIO_SERVER )
msg = buffer;
if( s_srvRecvAll( conn, msgbuf, NETIO_MSGLEN ) != NETIO_MSGLEN )
if( ! s_srvRecvAll( conn, msgbuf, NETIO_MSGLEN ) )
break;
uiMsg = HB_GET_LE_UINT32( msgbuf );
@@ -811,7 +811,7 @@ HB_FUNC( NETIO_SERVER )
if( size + conn->rootPathLen >= ( long ) sizeof( buffer ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( size + conn->rootPathLen + 1 );
msg[ size ] = '\0';
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else
{
@@ -844,7 +844,7 @@ HB_FUNC( NETIO_SERVER )
if( size + conn->rootPathLen >= ( long ) sizeof( buffer ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( size + conn->rootPathLen + 1 );
msg[ size ] = '\0';
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else
{
@@ -875,7 +875,7 @@ HB_FUNC( NETIO_SERVER )
if( HB_MAX( size, size2 ) + conn->rootPathLen >= ( long ) sizeof( buffer ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( HB_MAX( size, size2 ) + conn->rootPathLen + 1 );
msg[ size ] = '\0';
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else
{
@@ -885,7 +885,7 @@ HB_FUNC( NETIO_SERVER )
pszDirSpec = pszName ? hb_strdup( pszName ) : NULL;
msg[ size2 ] = '\0';
if( size2 && s_srvRecvAll( conn, msg, size2 ) != size2 )
if( size2 && ! s_srvRecvAll( conn, msg, size2 ) )
errCode = NETIO_ERR_READ;
else if( ! pszName )
errCode = NETIO_ERR_WRONG_FILE_PATH;
@@ -939,7 +939,7 @@ HB_FUNC( NETIO_SERVER )
if( size + conn->rootPathLen >= ( long ) sizeof( buffer ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( size + conn->rootPathLen + 1 );
msg[ size ] = '\0';
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else
{
@@ -990,7 +990,7 @@ HB_FUNC( NETIO_SERVER )
if( HB_MAX( size, size2 ) + conn->rootPathLen >= ( long ) sizeof( buffer ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( HB_MAX( size, size2 ) + conn->rootPathLen + 1 );
msg[ size ] = '\0';
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else
{
@@ -1001,7 +1001,7 @@ HB_FUNC( NETIO_SERVER )
szOldName = hb_strdup( szFile );
msg[ size2 ] = '\0';
if( s_srvRecvAll( conn, msg, size2 ) != size2 )
if( ! s_srvRecvAll( conn, msg, size2 ) )
errCode = NETIO_ERR_READ;
else if( ! szOldName )
errCode = NETIO_ERR_WRONG_FILE_PATH;
@@ -1038,7 +1038,7 @@ HB_FUNC( NETIO_SERVER )
if( size + conn->rootPathLen >= ( long ) sizeof( buffer ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( size + conn->rootPathLen + 1 );
msg[ size ] = '\0';
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else
{
@@ -1072,7 +1072,7 @@ HB_FUNC( NETIO_SERVER )
if( size + conn->rootPathLen >= ( long ) sizeof( buffer ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( size + conn->rootPathLen + 1 );
msg[ size ] = '\0';
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else
{
@@ -1107,7 +1107,7 @@ HB_FUNC( NETIO_SERVER )
if( size + conn->rootPathLen >= ( long ) sizeof( buffer ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( size + conn->rootPathLen + 1 );
msg[ size ] = '\0';
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else if( conn->filesCount >= NETIO_FILES_MAX )
errCode = NETIO_ERR_FILES_MAX;
@@ -1154,7 +1154,7 @@ HB_FUNC( NETIO_SERVER )
{
if( size >= ( long ) ( sizeof( buffer ) - NETIO_MSGLEN ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( size + NETIO_MSGLEN );
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else
{
@@ -1273,7 +1273,7 @@ HB_FUNC( NETIO_SERVER )
{
if( size >= ( long ) sizeof( buffer ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( size );
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else
{
@@ -1456,7 +1456,7 @@ HB_FUNC( NETIO_SERVER )
{
if( size >= ( long ) sizeof( buffer ) )
ptr = msg = ( HB_BYTE * ) hb_xgrab( size );
if( s_srvRecvAll( conn, msg, size ) != size )
if( ! s_srvRecvAll( conn, msg, size ) )
errCode = NETIO_ERR_READ;
else if( ! conn->rpc )
errCode = NETIO_ERR_UNSUPPORTED;
@@ -1642,7 +1642,7 @@ HB_FUNC( NETIO_SERVER )
else
len += NETIO_MSGLEN;
errCode = s_srvSendAll( conn, msg, len ) != len;
errCode = ! s_srvSendAll( conn, msg, len );
if( ptr )
hb_xfree( ptr );
@@ -1690,7 +1690,7 @@ HB_FUNC( NETIO_SRVSENDITEM )
stream = stream->next;
}
if( stream && stream->type == NETIO_SRVITEM )
fResult = s_srvSendAll( conn, msg, lLen ) == lLen;
fResult = s_srvSendAll( conn, msg, lLen );
hb_threadMutexUnlock( conn->mutex );
}
hb_xfree( msg );
@@ -1730,7 +1730,7 @@ HB_FUNC( NETIO_SRVSENDDATA )
stream = stream->next;
}
if( stream && stream->type == NETIO_SRVDATA )
fResult = s_srvSendAll( conn, msg, lLen ) == lLen;
fResult = s_srvSendAll( conn, msg, lLen );
hb_threadMutexUnlock( conn->mutex );
}
hb_xfree( msg );

View File

@@ -75,7 +75,7 @@ typedef struct _HB_ZNETSTREAM
}
HB_ZNETSTREAM;
#define HB_ZNET_BUFSIZE 16384
#define HB_ZNET_BUFSIZE 0x4000
#if MAX_MEM_LEVEL >= 8
# define HB_ZNET_MEM_LEVEL 8
@@ -292,47 +292,41 @@ long hb_znetRead( PHB_ZNETSTREAM pStream, HB_SOCKET sd, void * buffer, long len,
static long hb_znetStreamWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_MAXINT timeout )
{
long tosnd = HB_ZNET_BUFSIZE - pStream->wr.avail_out;
long snd = 0, rest = 0;
long snd = 0, rest = 0, tosnd;
if( pStream->crypt )
{
long size = ( long ) ( pStream->wr.next_out - pStream->crypt_out );
if( size > 2 )
rest = ( long ) ( pStream->wr.next_out - pStream->crypt_out );
if( rest > 2 )
{
HB_U16 uiLen = ( HB_U16 ) ( size - 2 );
HB_U16 uiLen = ( HB_U16 ) ( rest - 2 );
HB_PUT_BE_UINT16( pStream->crypt_out, uiLen );
uiLen = ( HB_U16 ) ( ( ( size + 7 ) ^ 0x07 ) & 0x07 );
if( ( uInt ) uiLen > pStream->wr.avail_out )
{
/* it may happen only if encryption was enabled in non empty
* buffer and the unencrypted part has not been flushed yet.
*/
rest = size;
}
else
uiLen = ( HB_U16 ) ( ( ( rest + 0x07 ) ^ 0x07 ) & 0x07 );
if( ( uInt ) uiLen <= pStream->wr.avail_out )
{
while( uiLen-- )
{
*pStream->wr.next_out++ = ( Byte ) 0; /* TODO: use better hashing data */
pStream->wr.avail_out--;
size++;
rest++;
}
/* encrypt the buffer */
for( tosnd = 0; tosnd < size; tosnd += 8 )
for( tosnd = 0; tosnd < rest; tosnd += 8 )
hb_znetEncrypt( pStream, pStream->crypt_out + tosnd );
rest = 0;
pStream->crypt_out = pStream->wr.next_out;
pStream->wr.next_out += 2;
if( pStream->wr.avail_out < 2 )
pStream->skip_out = 2 - pStream->wr.avail_out;
pStream->wr.avail_out -= 2 - pStream->skip_out;
}
tosnd = ( long ) ( pStream->crypt_out - pStream->outbuf );
}
else
tosnd -= 2;
rest = 0;
tosnd = ( long ) ( pStream->crypt_out - pStream->outbuf );
}
else
tosnd = HB_ZNET_BUFSIZE - pStream->wr.avail_out;
if( tosnd > 0 )
{