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:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user