2010-01-08 14:00 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/contrib/hbnetio/netiocli.c
    * pacified BCC warning

  * harbour/include/hbznet.h
  * harbour/src/rtl/hbznet.c
    + added support for blowfish encryption in HB_ZNETSTREAM
    + added C function
         void hb_znetEncryptKey( PHB_ZNETSTREAM pStream,
                                 const void * keydata, int keylen );
      which enables data encryption in HB_ZNETSTREAM
    + added 4-th parameter to <cPass> to .PRG HB_INETCOMPRESS() function:
         HB_INETCOMPRESS( <pSocket>, [<nCompressionLevel>], [<nStrategy>],
                          [<cPass>] )
         <cPass> is initial value to create blowfish key.
      Please test.
This commit is contained in:
Przemyslaw Czerpak
2010-01-08 13:00:37 +00:00
parent 7857d2d0eb
commit 25de114b61
4 changed files with 205 additions and 18 deletions

View File

@@ -17,6 +17,23 @@
past entries belonging to author(s): Viktor Szakats.
*/
2010-01-08 14:00 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/contrib/hbnetio/netiocli.c
* pacified BCC warning
* harbour/include/hbznet.h
* harbour/src/rtl/hbznet.c
+ added support for blowfish encryption in HB_ZNETSTREAM
+ added C function
void hb_znetEncryptKey( PHB_ZNETSTREAM pStream,
const void * keydata, int keylen );
which enables data encryption in HB_ZNETSTREAM
+ added 4-th parameter to <cPass> to .PRG HB_INETCOMPRESS() function:
HB_INETCOMPRESS( <pSocket>, [<nCompressionLevel>], [<nStrategy>],
[<cPass>] )
<cPass> is initial value to create blowfish key.
Please test.
2010-01-08 12:25 UTC+0100 Viktor Szakats (harbour.01 syenar.hu)
* config/wce/msvcarm.mk
! Fixed typo in prev modification.

View File

@@ -499,7 +499,7 @@ static const char * s_netio_params( int iMsg, const char * pszName, UINT32 * pSi
{
int iPCount = iMsg == NETIO_PROCIS ? 0 : hb_pcount(), i;
char * data = NULL, * itmData;
ULONG size = 0, itmSize;
ULONG size, itmSize;
size = ( ULONG ) strlen( pszName ) + 1;

View File

@@ -72,6 +72,7 @@ typedef void ( * HB_INET_CFUNC ) ( PHB_ZNETSTREAM );
extern HB_EXPORT int hb_znetError( PHB_ZNETSTREAM pStream );
extern HB_EXPORT PHB_ZNETSTREAM hb_znetOpen( int level, int strategy );
extern HB_EXPORT void hb_znetEncryptKey( PHB_ZNETSTREAM pStream, const void * keydata, int keylen );
extern HB_EXPORT void hb_znetClose( PHB_ZNETSTREAM pStream );
extern HB_EXPORT int hb_znetError( PHB_ZNETSTREAM pStream );
extern HB_EXPORT long hb_znetRead( PHB_ZNETSTREAM pStream, HB_SOCKET sd, void * buffer, long len, HB_LONG timeout );

View File

@@ -56,6 +56,7 @@
#include "hbapiitm.h"
#include "hbapierr.h"
#include "hbsocket.h"
#include "hbbfish.h"
#include "hbznet.h"
#include "hbzlib.ch"
@@ -66,8 +67,15 @@ typedef struct _HB_ZNETSTREAM
z_stream rd; /* input stream */
z_stream wr; /* output stream */
int err; /* error code for last stream operation */
int crypt; /* encryption */
uInt crypt_in; /* number of encrypted characters in buffer */
uInt crypt_size; /* size of encrypted block */
uInt skip_in; /* encryption block padding bytes */
uInt skip_out; /* room for block size */
Bytef * crypt_out; /* block size offset for encrypted blocks */
Bytef * inbuf; /* input buffer */
Bytef * outbuf; /* output buffer */
HB_BLOWFISH * bf;
}
HB_ZNETSTREAM;
@@ -95,6 +103,9 @@ void hb_znetClose( PHB_ZNETSTREAM pStream )
if( pStream->outbuf )
hb_xfree( pStream->outbuf );
if( pStream->bf )
hb_xfree( pStream->bf );
deflateEnd( &pStream->wr );
inflateEnd( &pStream->rd );
@@ -124,6 +135,55 @@ PHB_ZNETSTREAM hb_znetOpen( int level, int strategy )
return NULL;
}
/* set encryption key
*/
void hb_znetEncryptKey( PHB_ZNETSTREAM pStream, const void * keydata, int keylen )
{
if( pStream->crypt == 0 )
{
pStream->crypt = 1;
/* initialize encryption key */
pStream->bf = ( HB_BLOWFISH * ) hb_xgrab( sizeof( HB_BLOWFISH ) );
hb_blowfishInit( pStream->bf, keydata, keylen );
/* initialize input buffer */
pStream->skip_in = 0;
pStream->crypt_size = 0;
pStream->crypt_in = pStream->rd.avail_in;
pStream->rd.avail_in = 0;
/* initialize output buffer */
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;
else
pStream->skip_out = 0;
pStream->wr.avail_out -= 2 - pStream->skip_out;
}
}
static void hb_znetDecrypt( PHB_ZNETSTREAM pStream, Bytef * data )
{
UINT32 xl, xr;
xl = HB_GET_BE_UINT32( data );
xr = HB_GET_BE_UINT32( data + 4 );
hb_blowfishDecrypt( pStream->bf, &xl, &xr );
HB_PUT_BE_UINT32( data, xl );
HB_PUT_BE_UINT32( data + 4, xr );
}
static void hb_znetEncrypt( PHB_ZNETSTREAM pStream, Bytef * data )
{
UINT32 xl, xr;
xl = HB_GET_BE_UINT32( data );
xr = HB_GET_BE_UINT32( data + 4 );
hb_blowfishEncrypt( pStream->bf, &xl, &xr );
HB_PUT_BE_UINT32( data, xl );
HB_PUT_BE_UINT32( data + 4, xr );
}
/* read data using stream structure
*/
long hb_znetRead( PHB_ZNETSTREAM pStream, HB_SOCKET sd, void * buffer, long len, HB_LONG timeout )
@@ -138,17 +198,67 @@ long hb_znetRead( PHB_ZNETSTREAM pStream, HB_SOCKET sd, void * buffer, long len,
{
if( pStream->rd.avail_in == 0 && pStream->err == Z_STREAM_END )
{
if( pStream->rd.avail_out != ( uInt ) len )
timeout = 0;
rec = hb_socketRecv( sd, pStream->inbuf, HB_ZNET_BUFSIZE, 0, timeout );
if( rec <= 0 )
break;
pStream->rd.avail_in = ( uInt ) rec;
if( pStream->skip_in )
{
pStream->rd.next_in += pStream->skip_in;
pStream->skip_in = 0;
}
if( pStream->crypt_in && pStream->rd.next_in > pStream->inbuf )
memmove( pStream->inbuf, pStream->rd.next_in, pStream->crypt_in );
pStream->rd.next_in = pStream->inbuf;
if( !pStream->crypt || pStream->crypt_in < 8 )
{
if( pStream->rd.avail_out != ( uInt ) len )
timeout = 0;
rec = hb_socketRecv( sd, pStream->inbuf + pStream->crypt_in, HB_ZNET_BUFSIZE - pStream->crypt_in, 0, timeout );
if( rec <= 0 )
break;
}
if( pStream->crypt )
{
pStream->crypt_in += rec;
if( pStream->crypt_size == 0 )
{
if( pStream->crypt_in >= 8 )
{
hb_znetDecrypt( pStream, pStream->rd.next_in );
pStream->crypt_size = HB_GET_BE_UINT16( pStream->rd.next_in );
pStream->rd.next_in += 2;
pStream->crypt_in -= 8;
rec = HB_MIN( pStream->crypt_size, 6 );
pStream->crypt_size -= ( uInt ) rec;
pStream->rd.avail_in += ( uInt ) rec;
pStream->skip_in = ( uInt ) ( 6 - rec );
rec = 0;
}
}
if( pStream->skip_in == 0 )
{
long l = ( pStream->crypt_size + 0x07 ) & ~0x07;
rec = pStream->crypt_in & ~0x07;
if( rec > l )
rec = l;
/* decrypt the buffer */
for( l = 0; l < rec; l += 8 )
hb_znetDecrypt( pStream, pStream->rd.next_in + pStream->rd.avail_in + l );
pStream->crypt_in -= rec;
if( rec > pStream->crypt_size )
{
pStream->skip_in = rec - pStream->crypt_size;
rec = pStream->crypt_size;
}
pStream->crypt_size -= rec;
}
}
pStream->rd.avail_in += ( uInt ) rec;
if( pStream->rd.avail_in == 0 )
break;
rec = 0;
}
pStream->err = inflate( &pStream->rd, Z_SYNC_FLUSH );
if( pStream->err == Z_BUF_ERROR )
if( pStream->err == Z_BUF_ERROR && pStream->rd.avail_in == 0 )
pStream->err = Z_STREAM_END;
if( pStream->err != Z_OK && pStream->err != Z_STREAM_END )
break;
@@ -162,17 +272,71 @@ long hb_znetRead( PHB_ZNETSTREAM pStream, HB_SOCKET sd, void * buffer, long len,
static long hb_znetStreamWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_LONG timeout )
{
long tosnd = HB_ZNET_BUFSIZE - pStream->wr.avail_out;
long snd = 0;
long snd = 0, rest = 0;
if( pStream->crypt )
{
long size = ( long ) ( pStream->wr.next_out - pStream->crypt_out );
if( size > 2 )
{
UINT16 uiLen = ( UINT16 ) ( size - 2 );
HB_PUT_BE_UINT16( pStream->crypt_out, uiLen );
uiLen = ( UINT16 ) ( ( ( size + 7 ) ^ 0x07 ) & 0x07 );
if( 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
{
while( uiLen-- )
{
*pStream->wr.next_out++ = ( Byte ) 0; /* TODO: use better hashing data */
pStream->wr.avail_out--;
size++;
}
/* encrypt the buffer */
for( tosnd = 0; tosnd < size; tosnd += 8 )
hb_znetEncrypt( pStream, pStream->crypt_out + tosnd );
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;
}
if( tosnd > 0 )
{
snd = hb_socketSend( sd, pStream->outbuf, tosnd, 0, timeout );
if( snd > 0 )
{
if( snd < tosnd )
memmove( pStream->outbuf, pStream->outbuf + snd, tosnd - snd );
tosnd += rest - snd;
if( tosnd > 0 )
memmove( pStream->outbuf, pStream->outbuf + snd, tosnd );
pStream->wr.avail_out += ( uInt ) snd;
pStream->wr.next_out = pStream->outbuf + tosnd - snd;
pStream->wr.next_out -= snd;
pStream->crypt_out -= snd;
if( pStream->skip_out )
{
if( pStream->skip_out <= pStream->wr.avail_out )
{
pStream->wr.avail_out -= pStream->skip_out;
pStream->skip_out = 0;
}
else
{
pStream->skip_out -= pStream->wr.avail_out;
pStream->wr.avail_out = 0;
}
}
}
}
return snd;
@@ -183,12 +347,14 @@ static long hb_znetStreamWrite( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_LONG ti
*/
long hb_znetFlush( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_LONG timeout )
{
uInt uiSize = HB_ZNET_BUFSIZE - ( pStream->crypt ? -2 : 0 );
if( pStream->wr.avail_out > 0 )
pStream->err = deflate( &pStream->wr, Z_SYNC_FLUSH );
else
pStream->err = Z_OK;
while( pStream->wr.avail_out < HB_ZNET_BUFSIZE )
while( pStream->wr.avail_out < uiSize )
{
if( hb_znetStreamWrite( pStream, sd, timeout ) <= 0 )
break;
@@ -197,7 +363,7 @@ long hb_znetFlush( PHB_ZNETSTREAM pStream, HB_SOCKET sd, HB_LONG timeout )
pStream->err = deflate( &pStream->wr, Z_SYNC_FLUSH );
}
return HB_ZNET_BUFSIZE - pStream->wr.avail_out;
return uiSize - pStream->wr.avail_out;
}
/* write data using stream structure
@@ -263,11 +429,14 @@ HB_FUNC( HB_INETCOMPRESS )
PHB_ZNETSTREAM pStream = hb_znetOpen( iLevel, iStrategy );
if( pStream == NULL )
pItem = NULL; /* to force RTE */
if( ! hb_znetInetInitialize( pItem, pStream, hb_znetRead, hb_znetWrite,
hb_znetFlush, hb_znetClose ) )
if( hb_znetInetInitialize( pItem, pStream, hb_znetRead, hb_znetWrite,
hb_znetFlush, hb_znetClose ) )
{
if( pStream )
hb_znetClose( pStream );
int keylen = ( int ) hb_parclen( 4 );
if( keylen )
hb_znetEncryptKey( pStream, hb_parc( 4 ), keylen );
}
else if( pStream )
hb_znetClose( pStream );
}
}