From 5bb312acf997d03ded29d9476c4dcdaab59fa1e4 Mon Sep 17 00:00:00 2001 From: endaco Date: Wed, 5 Jun 2024 10:26:40 +0200 Subject: [PATCH 1/7] Ensure compatibility with Debian 12: update dattime3.c, firebird.c, setdate.c, settime.c, and arc4.c --- contrib/hbct/dattime3.c | 39 +++++++++++++---------- contrib/hbfbird/firebird.c | 63 ++++++++++++++++++------------------ contrib/hbnf/setdate.c | 17 +++++----- contrib/hbnf/settime.c | 22 ++++++++----- src/rtl/arc4.c | 65 ++++++++++++++++++-------------------- 5 files changed, 108 insertions(+), 98 deletions(-) diff --git a/contrib/hbct/dattime3.c b/contrib/hbct/dattime3.c index 073e52fb4d..fa19cbc95a 100644 --- a/contrib/hbct/dattime3.c +++ b/contrib/hbct/dattime3.c @@ -130,6 +130,10 @@ HB_FUNC( TIMEVALID ) hb_retl( _hb_timeValid( hb_parc( 1 ), hb_parclen( 1 ), NULL ) ); } +#include + +// ... altres parts del codi ... + HB_FUNC( SETTIME ) { HB_BOOL fResult = HB_FALSE; @@ -147,14 +151,18 @@ HB_FUNC( SETTIME ) st.wMilliseconds = ( WORD ) iTime[ 3 ] * 10; fResult = SetLocalTime( &st ); #elif defined( HB_OS_LINUX ) && ! defined( HB_OS_ANDROID ) && ! defined( __WATCOMC__ ) - /* stime() exists only in SVr4, SVID, X/OPEN and Linux */ - HB_ULONG lNewTime; - time_t tm; - - lNewTime = iTime[ 0 ] * 3600 + iTime[ 1 ] * 60 + iTime[ 2 ]; - tm = time( NULL ); - tm += lNewTime - ( tm % 86400 ); - fResult = stime( &tm ) == 0; + struct timespec ts; + time_t now = time(NULL); + struct tm *tm_info = localtime(&now); + + tm_info->tm_hour = iTime[ 0 ]; + tm_info->tm_min = iTime[ 1 ]; + tm_info->tm_sec = iTime[ 2 ]; + + ts.tv_sec = mktime(tm_info); + ts.tv_nsec = 0; + + fResult = clock_settime(CLOCK_REALTIME, &ts) == 0; #elif defined( HB_OS_DOS ) union REGS regs; regs.h.ah = 45; @@ -190,14 +198,13 @@ HB_FUNC( SETDATE ) st.wDayOfWeek = ( WORD ) hb_dateJulianDOW( lDate ); fResult = SetLocalTime( &st ); #elif defined( HB_OS_LINUX ) && ! defined( HB_OS_ANDROID ) && ! defined( __WATCOMC__ ) - /* stime() exists only in SVr4, SVID, X/OPEN and Linux */ - long lNewDate; - time_t tm; - - lNewDate = lDate - hb_dateEncode( 1970, 1, 1 ); - tm = time( NULL ); - tm = lNewDate * 86400 + ( tm % 86400 ); - fResult = stime( &tm ) == 0; + struct timespec ts; + struct tm tm_info = { .tm_year = iYear - 1900, .tm_mon = iMonth - 1, .tm_mday = iDay }; + + ts.tv_sec = mktime(&tm_info); + ts.tv_nsec = 0; + + fResult = clock_settime(CLOCK_REALTIME, &ts) == 0; #elif defined( HB_OS_DOS ) union REGS regs; regs.h.ah = 43; diff --git a/contrib/hbfbird/firebird.c b/contrib/hbfbird/firebird.c index 66d869c498..2cc73d0de8 100644 --- a/contrib/hbfbird/firebird.c +++ b/contrib/hbfbird/firebird.c @@ -149,41 +149,42 @@ HB_FUNC( FBCREATEDB ) hb_retnl( 0 ); } -HB_FUNC( FBCONNECT ) +HB_FUNC(FBCONNECT) { - ISC_STATUS_ARRAY status; - isc_db_handle db = ( isc_db_handle ) 0; - const char * db_connect = hb_parcx( 1 ); - const char * user = hb_parcx( 2 ); - const char * passwd = hb_parcx( 3 ); - char dpb[ 128 ]; - short i = 0; - int len; - - /* FIXME: Possible buffer overflow. Use hb_snprintf(). */ - dpb[ i++ ] = isc_dpb_version1; - dpb[ i++ ] = isc_dpb_user_name; - len = ( int ) strlen( user ); - if( len > ( int ) ( sizeof( dpb ) - i - 4 ) ) - len = ( int ) ( sizeof( dpb ) - i - 4 ); - dpb[ i++ ] = ( char ) len; - hb_strncpy( &( dpb[ i ] ), user, len ); - i += ( short ) len; - dpb[ i++ ] = isc_dpb_password; - len = ( int ) strlen( passwd ); - if( len > ( int ) ( sizeof( dpb ) - i - 2 ) ) - len = ( int ) ( sizeof( dpb ) - i - 2 ); - dpb[ i++ ] = ( char ) len; - hb_strncpy( &( dpb[ i ] ), passwd, len ); - i += ( short ) len; - - if( isc_attach_database( status, 0, db_connect, &db, i, dpb ) ) - hb_retnl( isc_sqlcode( status ) ); - else - hb_FB_db_handle_ret( db ); + ISC_STATUS_ARRAY status; + isc_db_handle db = (isc_db_handle)0; + const char *db_connect = hb_parcx(1); + const char *user = hb_parcx(2); + const char *passwd = hb_parcx(3); + char dpb[128]; + short i = 0; + int len; + + i += hb_snprintf(dpb + i, sizeof(dpb) - i, "%c", isc_dpb_version1); + i += hb_snprintf(dpb + i, sizeof(dpb) - i, "%c", isc_dpb_user_name); + len = (int)strlen(user); + if (len > (int)(sizeof(dpb) - i - 4)) + len = (int)(sizeof(dpb) - i - 4); + i += hb_snprintf(dpb + i, sizeof(dpb) - i, "%c", (char)len); + hb_strncpy(&(dpb[i]), user, len); + i += (short)len; + i += hb_snprintf(dpb + i, sizeof(dpb) - i, "%c", isc_dpb_password); + len = (int)strlen(passwd); + if (len > (int)(sizeof(dpb) - i - 2)) + len = (int)(sizeof(dpb) - i - 2); + i += hb_snprintf(dpb + i, sizeof(dpb) - i, "%c", (char)len); + hb_strncpy(&(dpb[i]), passwd, len); + i += (short)len; + + if (isc_attach_database(status, 0, db_connect, &db, i, dpb)) + hb_retnl(isc_sqlcode(status)); + else + hb_FB_db_handle_ret(db); } + + HB_FUNC( FBCLOSE ) { isc_db_handle db = hb_FB_db_handle_par( 1 ); diff --git a/contrib/hbnf/setdate.c b/contrib/hbnf/setdate.c index 6587fb5df2..9ba42c8f56 100644 --- a/contrib/hbnf/setdate.c +++ b/contrib/hbnf/setdate.c @@ -1,4 +1,5 @@ -/* Rewritten in 2012 by Viktor Szakats and kept in the +/* + * Rewritten in 2012 by Viktor Szakats and kept in the public domain. This is an original work by Glenn Scott and is placed in the public domain. @@ -57,14 +58,14 @@ HB_FUNC( FT_SETDATE ) } #elif defined( HB_OS_LINUX ) && ! defined( HB_OS_ANDROID ) && ! defined( __WATCOMC__ ) { - /* stime() exists only in SVr4, SVID, X/OPEN and Linux */ - long lNewDate; - time_t tm; + /* clock_settime() per a sistemes Linux moderns */ + struct timespec ts; + struct tm tm_info = { .tm_year = iYear - 1900, .tm_mon = iMonth - 1, .tm_mday = iDay }; - lNewDate = lDate - hb_dateEncode( 1970, 1, 1 ); - tm = time( NULL ); - tm = lNewDate * 86400 + ( tm % 86400 ); - fResult = stime( &tm ) == 0; + ts.tv_sec = mktime(&tm_info); + ts.tv_nsec = 0; + + fResult = clock_settime(CLOCK_REALTIME, &ts) == 0; } #elif defined( HB_OS_DOS ) { diff --git a/contrib/hbnf/settime.c b/contrib/hbnf/settime.c index 74bf246c79..b4a1cf5ccf 100644 --- a/contrib/hbnf/settime.c +++ b/contrib/hbnf/settime.c @@ -1,4 +1,5 @@ -/* Rewritten in 2012 by Viktor Szakats and kept in the +/* + * Rewritten in 2012 by Viktor Szakats and kept in the public domain. This is an original work by Glenn Scott and is placed in the public domain. @@ -67,14 +68,19 @@ HB_FUNC( FT_SETTIME ) } #elif defined( HB_OS_LINUX ) && ! defined( HB_OS_ANDROID ) && ! defined( __WATCOMC__ ) { - /* stime() exists only in SVr4, SVID, X/OPEN and Linux */ - HB_ULONG lNewTime; - time_t tm; + /* clock_settime() per a sistemes Linux moderns */ + struct timespec ts; + time_t now = time(NULL); + struct tm *tm_info = localtime(&now); - lNewTime = iHour * 3600 + iMinute * 60 + iSeconds; - tm = time( NULL ); - tm += lNewTime - ( tm % 86400 ); - fResult = stime( &tm ) == 0; + tm_info->tm_hour = iHour; + tm_info->tm_min = iMinute; + tm_info->tm_sec = iSeconds; + + ts.tv_sec = mktime(tm_info); + ts.tv_nsec = 0; + + fResult = clock_settime(CLOCK_REALTIME, &ts) == 0; } #elif defined( HB_OS_DOS ) { diff --git a/src/rtl/arc4.c b/src/rtl/arc4.c index 1eaf74335c..8e2d3bf1b0 100644 --- a/src/rtl/arc4.c +++ b/src/rtl/arc4.c @@ -73,7 +73,7 @@ # include # include # ifdef HAVE_SYS_SYSCTL_H -# include +# include # if ! defined( HB_OS_LINUX ) && defined( KERN_ARND ) # define HAVE_DECL_KERN_ARND # endif @@ -486,42 +486,37 @@ static void arc4_seed( void ) arc4_seed_rand(); } -static void arc4_stir( void ) -{ - int i; - - if( ! rs_initialized ) - { - arc4_init(); - rs_initialized = 1; - } - - arc4_seed(); - - /* - * Discard early keystream, as per recommendations in - * "Weaknesses in the Key Scheduling Algorithm of RC4" by - * Scott Fluhrer, Itsik Mantin, and Adi Shamir. - * https://web.archive.org/web/www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps - * - * Ilya Mironov's "(Not So) Random Shuffles of RC4" suggests that - * we drop at least 2*256 bytes, with 12*256 as a conservative - * value. - * - * RFC4345 says to drop 6*256. - * - * At least some versions of this code drop 4*256, in a mistaken - * belief that "words" in the Fluhrer/Mantin/Shamir paper refers - * to processor words. - * - * We add another sect to the cargo cult, and choose 12*256. - */ - for( i = 0; i < 12 * 256; i++ ) - ( void ) arc4_getbyte(); - - arc4_count = BYTES_BEFORE_RESEED; +static void arc4_stir(void) { + int i; + unsigned char rnd[128]; + + if (!rs_initialized) { + arc4_init(); + rs_initialized = 1; + } + + // Obtenir entropia de /dev/urandom + int fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) { + perror("open /dev/urandom"); + return; + } + if (read(fd, rnd, sizeof(rnd)) != sizeof(rnd)) { + perror("read /dev/urandom"); + close(fd); + return; + } + close(fd); + + for (i = 0; i < sizeof(rnd); i++) { + rs.s[i] = rnd[i]; + } + + rs.i = rs.j = 0; + arc4_count = 256; } + static void arc4_stir_if_needed( void ) { #if defined( NO_PID_CHECK ) From d9744bdd8047f20ff41d1afdd6ae4cc2a710c97d Mon Sep 17 00:00:00 2001 From: endaco Date: Wed, 5 Jun 2024 16:37:09 +0200 Subject: [PATCH 2/7] Remove unnecessary backup file src/rtl/arc4.c~ --- contrib/hbct/dattime3.c | 4 ---- src/rtl/arc4.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/contrib/hbct/dattime3.c b/contrib/hbct/dattime3.c index fa19cbc95a..f1ef5a64dc 100644 --- a/contrib/hbct/dattime3.c +++ b/contrib/hbct/dattime3.c @@ -130,10 +130,6 @@ HB_FUNC( TIMEVALID ) hb_retl( _hb_timeValid( hb_parc( 1 ), hb_parclen( 1 ), NULL ) ); } -#include - -// ... altres parts del codi ... - HB_FUNC( SETTIME ) { HB_BOOL fResult = HB_FALSE; diff --git a/src/rtl/arc4.c b/src/rtl/arc4.c index 8e2d3bf1b0..9a51a98e1d 100644 --- a/src/rtl/arc4.c +++ b/src/rtl/arc4.c @@ -495,7 +495,7 @@ static void arc4_stir(void) { rs_initialized = 1; } - // Obtenir entropia de /dev/urandom + // Obtain entropy from /dev/urandom int fd = open("/dev/urandom", O_RDONLY); if (fd < 0) { perror("open /dev/urandom"); From fbe5fea00d4361824d267e4b32b91112f3e9c8a2 Mon Sep 17 00:00:00 2001 From: endaco Date: Wed, 5 Jun 2024 22:59:25 +0200 Subject: [PATCH 3/7] Fix: Resolved issues with hb_langSelect in contrib/hbtest/core.prg - Replaced hb_langSelect with __hb_langSelect to prevent crashes during repetitive tests. --- contrib/hbct/tests/test.prg | 24 ++++++++++++++++-------- contrib/hbtest/core.prg | 8 +++++--- contrib/hbtest/tests/test.prg | 1 + 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/contrib/hbct/tests/test.prg b/contrib/hbct/tests/test.prg index d6879bc01c..e1fd7bb290 100644 --- a/contrib/hbct/tests/test.prg +++ b/contrib/hbct/tests/test.prg @@ -1,11 +1,14 @@ #require "hbct" #require "hbtest" + + PROCEDURE Main() LOCAL nTotal LOCAL a, b - + + HBTEST AddAscii( "0000", 1, 1 ) IS "1000" HBTEST AddAscii( "0000", 1 ) IS "0001" HBTEST AddAscii( "AAAA", -255, 1 ) IS "BAAA" @@ -116,16 +119,20 @@ PROCEDURE Main() HBTEST CharSub( "012345678", hb_BChar( 255 ) ) IS "123456789" HBTEST CharSub( "012345678", hb_BChar( 255 ) + hb_BChar( 254 ) ) IS "133557799" + HBTEST CharRepl( "abcdefghij", "jhfdb", "12345" ) IS "55542" + HBTEST CharRepl( "1234", "1234", "234A" ) IS "AAAA" + HBTEST CharRepl( "1234", "1234", "234A", .T. ) IS "234A" + HBTEST CharRepl( "1234", "1x2y3z", "abcd" ) IS "axbycz" + HBTEST CharRepl( "abcdefghij", "jhfdb", "1234567890" ) IS "08642" + + HBTEST CharShl( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ) + hb_BChar( 0 ) + hb_BChar( 0 ) + hb_BChar( 0 ) HBTEST CharShr( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 0 ) + hb_BChar( 0 ) + hb_BChar( 0 ) + hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) HBTEST CharRll( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ) + hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) HBTEST CharRlr( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ) + hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) - HBTEST CharRepl( "1234", "1x2y3z", "abcd" ) IS "axbycz" - HBTEST CharRepl( "abcdefghij", "jhfdb", "1234567890" ) IS "08642" - HBTEST CharRepl( "abcdefghij", "jhfdb", "12345" ) IS "55542" - HBTEST CharRepl( "1234", "1234", "234A" ) IS "AAAA" - HBTEST CharRepl( "1234", "1234", "234A", .T. ) IS "234A" + + HBTEST CharSort( "qwert" ) IS "eqrtw" HBTEST CharSort( "qwert", 2 ) IS "erqwt" @@ -261,7 +268,7 @@ PROCEDURE Main() HBTEST ( CSetAtMupa( .T. ), WordRepl( "aa", "1aaaa", "ba" ) ) IS "1abaa" HBTEST ( CSetAtMupa( .T. ), WordRepl( "aa", "1aaaa", "ba", .T. ) ) IS "1bbba" - hb_langSelect( "en" ) + //hb_langSelect( "en" ) HBTEST CToDoW() IS 0 HBTEST CToDoW( 1 ) IS 0 @@ -297,6 +304,7 @@ PROCEDURE Main() HBTEST StrSwap( NIL, NIL ) IS "" HBTEST Crypt( "Hello World!", "pw" ) IS e"\222\365?\003{\375$\324\331\246\017\177" - HBTEST Crypt( e"\222\365?\003{\375$\324\331\246\017\177", "pw" ) IS "Hello World!" + HBTEST Crypt( e"\222\365?\003{\375$\324\331\246\017\177", "pw" ) IS "Hello World!" + RETURN diff --git a/contrib/hbtest/core.prg b/contrib/hbtest/core.prg index 7aca6a595c..d0995b0dc4 100644 --- a/contrib/hbtest/core.prg +++ b/contrib/hbtest/core.prg @@ -137,8 +137,10 @@ PROCEDURE hbtest_Call( cBlock, bBlock, xResultExpected ) cBlock := "[Preprocessor error]" lPPError := .T. ENDIF - - cLangOld := hb_langSelect( "en" ) /* to always have RTEs in one language */ + + + cLangOld := __hb_langSelect( "en" ) /* to always have RTEs in one language */ + IF ! s_lBanner s_lBanner := .T. @@ -153,7 +155,7 @@ PROCEDURE hbtest_Call( cBlock, bBlock, xResultExpected ) lRTE := .T. END SEQUENCE - hb_langSelect( cLangOld ) + __hb_langSelect( cLangOld ) IF lRTE lFailed := ! XToStr( xResult ) == XToStr( xResultExpected ) diff --git a/contrib/hbtest/tests/test.prg b/contrib/hbtest/tests/test.prg index 5f65acdd7a..87e745d383 100644 --- a/contrib/hbtest/tests/test.prg +++ b/contrib/hbtest/tests/test.prg @@ -5,6 +5,7 @@ PROCEDURE Main() LOCAL tmp, hbtest_Table_OK + hb_dbCreateTemp( "w_TEST", { { "TESTM", "M", 10, 0 } } ) dbAppend() From 75b5f755d39fa4c880430007f6055e86bde08e46 Mon Sep 17 00:00:00 2001 From: endaco Date: Thu, 6 Jun 2024 05:52:34 +0200 Subject: [PATCH 4/7] Revert to previous version of: contrib/hbct/tests/test.prg Revert to previous version of: contrib/hbtest/tests/test.prg --- contrib/hbct/tests/test.prg | 24 ++++++++---------------- contrib/hbtest/tests/test.prg | 1 - 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/contrib/hbct/tests/test.prg b/contrib/hbct/tests/test.prg index e1fd7bb290..d6879bc01c 100644 --- a/contrib/hbct/tests/test.prg +++ b/contrib/hbct/tests/test.prg @@ -1,14 +1,11 @@ #require "hbct" #require "hbtest" - - PROCEDURE Main() LOCAL nTotal LOCAL a, b - - + HBTEST AddAscii( "0000", 1, 1 ) IS "1000" HBTEST AddAscii( "0000", 1 ) IS "0001" HBTEST AddAscii( "AAAA", -255, 1 ) IS "BAAA" @@ -119,20 +116,16 @@ PROCEDURE Main() HBTEST CharSub( "012345678", hb_BChar( 255 ) ) IS "123456789" HBTEST CharSub( "012345678", hb_BChar( 255 ) + hb_BChar( 254 ) ) IS "133557799" - HBTEST CharRepl( "abcdefghij", "jhfdb", "12345" ) IS "55542" - HBTEST CharRepl( "1234", "1234", "234A" ) IS "AAAA" - HBTEST CharRepl( "1234", "1234", "234A", .T. ) IS "234A" - HBTEST CharRepl( "1234", "1x2y3z", "abcd" ) IS "axbycz" - HBTEST CharRepl( "abcdefghij", "jhfdb", "1234567890" ) IS "08642" - - HBTEST CharShl( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ) + hb_BChar( 0 ) + hb_BChar( 0 ) + hb_BChar( 0 ) HBTEST CharShr( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 0 ) + hb_BChar( 0 ) + hb_BChar( 0 ) + hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) HBTEST CharRll( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ) + hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) HBTEST CharRlr( hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) + hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ), 3 ) IS hb_BChar( 32 ) + hb_BChar( 64 ) + hb_BChar( 128 ) + hb_BChar( 1 ) + hb_BChar( 2 ) + hb_BChar( 4 ) + hb_BChar( 8 ) + hb_BChar( 16 ) - - + HBTEST CharRepl( "1234", "1x2y3z", "abcd" ) IS "axbycz" + HBTEST CharRepl( "abcdefghij", "jhfdb", "1234567890" ) IS "08642" + HBTEST CharRepl( "abcdefghij", "jhfdb", "12345" ) IS "55542" + HBTEST CharRepl( "1234", "1234", "234A" ) IS "AAAA" + HBTEST CharRepl( "1234", "1234", "234A", .T. ) IS "234A" HBTEST CharSort( "qwert" ) IS "eqrtw" HBTEST CharSort( "qwert", 2 ) IS "erqwt" @@ -268,7 +261,7 @@ PROCEDURE Main() HBTEST ( CSetAtMupa( .T. ), WordRepl( "aa", "1aaaa", "ba" ) ) IS "1abaa" HBTEST ( CSetAtMupa( .T. ), WordRepl( "aa", "1aaaa", "ba", .T. ) ) IS "1bbba" - //hb_langSelect( "en" ) + hb_langSelect( "en" ) HBTEST CToDoW() IS 0 HBTEST CToDoW( 1 ) IS 0 @@ -304,7 +297,6 @@ PROCEDURE Main() HBTEST StrSwap( NIL, NIL ) IS "" HBTEST Crypt( "Hello World!", "pw" ) IS e"\222\365?\003{\375$\324\331\246\017\177" - HBTEST Crypt( e"\222\365?\003{\375$\324\331\246\017\177", "pw" ) IS "Hello World!" - + HBTEST Crypt( e"\222\365?\003{\375$\324\331\246\017\177", "pw" ) IS "Hello World!" RETURN diff --git a/contrib/hbtest/tests/test.prg b/contrib/hbtest/tests/test.prg index 87e745d383..5f65acdd7a 100644 --- a/contrib/hbtest/tests/test.prg +++ b/contrib/hbtest/tests/test.prg @@ -5,7 +5,6 @@ PROCEDURE Main() LOCAL tmp, hbtest_Table_OK - hb_dbCreateTemp( "w_TEST", { { "TESTM", "M", 10, 0 } } ) dbAppend() From 5577ba17004b585c5a18c6756b90103c7922a729 Mon Sep 17 00:00:00 2001 From: endaco Date: Fri, 7 Jun 2024 13:05:09 +0200 Subject: [PATCH 5/7] Error compiling on windows modified: src/rtl/arc4.c --- src/rtl/arc4.c | 297 +++++++------------------------------------------ 1 file changed, 41 insertions(+), 256 deletions(-) diff --git a/src/rtl/arc4.c b/src/rtl/arc4.c index 9a51a98e1d..5969a7f254 100644 --- a/src/rtl/arc4.c +++ b/src/rtl/arc4.c @@ -48,36 +48,11 @@ #include "hbdate.h" #include "hbthread.h" -/* XXX: Check and possibly extend this to other Unix-like platforms */ -#if ( defined( HB_OS_BSD ) && ! defined( HB_OS_DARWIN ) ) || \ - ( defined( HB_OS_LINUX ) && \ - ! defined( HB_OS_ANDROID ) && \ - ! defined( __WATCOMC__ ) && \ - ! defined( __EMSCRIPTEN__ ) ) -# define HAVE_SYS_SYSCTL_H -# define HAVE_DECL_CTL_KERN -# define HAVE_DECL_KERN_RANDOM -# if defined( HB_OS_LINUX ) -# define HAVE_DECL_RANDOM_UUID -# endif -#endif - #if defined( HB_OS_WIN ) # include #elif defined( HB_OS_DOS ) || defined( HB_OS_OS2 ) # include #else -# if ! defined( __WATCOMC__ ) -# include -# endif -# include -# include -# ifdef HAVE_SYS_SYSCTL_H -# include -# if ! defined( HB_OS_LINUX ) && defined( KERN_ARND ) -# define HAVE_DECL_KERN_ARND -# endif -# endif # include # include #endif @@ -203,182 +178,7 @@ static int arc4_seed_win( void ) } #endif /* HB_OS_WIN */ -#if defined( HAVE_SYS_SYSCTL_H ) - -#if defined( HAVE_DECL_CTL_KERN ) && defined( HAVE_DECL_KERN_RANDOM ) && \ - defined( HAVE_DECL_RANDOM_UUID ) - -#define TRY_SEED_SYSCTL_LINUX -static int arc4_seed_sysctl_linux( void ) -{ - /* - * Based on code by William Ahern, this function tries to use the - * RANDOM_UUID sysctl to get entropy from the kernel. This can work - * even if /dev/urandom is inaccessible for some reason (e.g., we're - * running in a chroot). - */ - int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID }; - HB_U8 buf[ ADD_ENTROPY ]; - size_t len, n; - unsigned int i; - int any_set; - - memset( buf, 0, sizeof( buf ) ); - - for( len = 0; len < sizeof( buf ); len += n ) - { - n = sizeof( buf ) - len; - - if( sysctl( mib, 3, &buf[ len ], &n, NULL, 0 ) != 0 ) - return -1; - } - - /* make sure that the buffer actually got set. */ - for( i = 0, any_set = 0; i < sizeof( buf ); ++i ) - any_set |= buf[ i ]; - - if( ! any_set ) - return -1; - - arc4_addrandom( buf, sizeof( buf ) ); - memset( buf, 0, sizeof( buf ) ); - - return 0; -} -#endif /* HAVE_DECL_CTL_KERN && HAVE_DECL_KERN_RANDOM && HAVE_DECL_RANDOM_UUID */ - -#if defined( HAVE_DECL_CTL_KERN ) && defined( HAVE_DECL_KERN_ARND ) - -#define TRY_SEED_SYSCTL_BSD -static int arc4_seed_sysctl_bsd( void ) -{ - /* - * Based on code from William Ahern and from OpenBSD, this function - * tries to use the KERN_ARND syscall to get entropy from the kernel. - * This can work even if /dev/urandom is inaccessible for some reason - * (e.g., we're running in a chroot). - */ - int mib[] = { CTL_KERN, KERN_ARND }; - HB_U8 buf[ ADD_ENTROPY ]; - size_t len, n; - int i, any_set; - - memset( buf, 0, sizeof( buf ) ); - - len = sizeof( buf ); - if( sysctl( mib, 2, buf, &len, NULL, 0 ) == -1 ) - { - for( len = 0; len < sizeof( buf ); len += sizeof( unsigned ) ) - { - n = sizeof( unsigned ); - - if( n + len > sizeof( buf ) ) - n = len - sizeof( buf ); - - if( sysctl( mib, 2, &buf[ len ], &n, NULL, 0 ) == -1 ) - return -1; - } - } - - /* make sure that the buffer actually got set. */ - for( i = any_set = 0; i < ( int ) sizeof( buf ); ++i ) - any_set |= buf[ i ]; - - if( ! any_set ) - return -1; - - arc4_addrandom( buf, sizeof( buf ) ); - memset( buf, 0, sizeof( buf ) ); - - return 0; -} -#endif /* HAVE_DECL_CTL_KERN && HAVE_DECL_KERN_ARND */ - -#endif /* defined( HAVE_SYS_SYSCTL_H ) */ - -#if defined( HB_OS_LINUX ) - -#define TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID -static _HB_INLINE_ int hex_char_to_int( char c ) -{ - switch( c ) - { - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; - case 'A': case 'a': return 10; - case 'B': case 'b': return 11; - case 'C': case 'c': return 12; - case 'D': case 'd': return 13; - case 'E': case 'e': return 14; - case 'F': case 'f': return 15; - } - - return -1; -} - -static int arc4_seed_proc_sys_kernel_random_uuid( void ) -{ - /* - * Occasionally, somebody will make /proc/sys accessible in a chroot, - * but not /dev/urandom. Let's try /proc/sys/kernel/random/uuid. - * Its format is stupid, so we need to decode it from hex. - */ - char buf[ 128 ]; - HB_U8 entropy[ 64 ]; - int bytes, i, nybbles; - - for( bytes = 0; bytes < ADD_ENTROPY; ) - { - int fd = open( "/proc/sys/kernel/random/uuid", O_RDONLY, 0 ); - int n; - - if( fd < 0 ) - return -1; - - n = read( fd, buf, sizeof( buf ) ); - close( fd ); - - if( n <= 0 ) - return -1; - - memset( entropy, 0, sizeof( entropy ) ); - for( i = nybbles = 0; i < n; ++i ) - { - if( HB_ISXDIGIT( buf[ i ] ) ) - { - int nyb = hex_char_to_int( buf[ i ] ); - - if( nybbles & 1 ) - entropy[ nybbles / 2 ] |= nyb; - else - entropy[ nybbles / 2 ] |= nyb << 4; - - ++nybbles; - } - } - if( nybbles < 2 ) - return -1; - - arc4_addrandom( entropy, nybbles / 2 ); - bytes += nybbles / 2; - } - - memset( entropy, 0, sizeof( entropy ) ); - memset( buf, 0, sizeof( buf ) ); - - return 0; -} -#endif /* HB_OS_LINUX */ - -#if defined( HB_OS_UNIX ) +#if defined( HB_OS_LINUX ) || defined( HB_OS_UNIX ) #define TRY_SEED_URANDOM static int arc4_seed_urandom( void ) @@ -417,7 +217,7 @@ static int arc4_seed_urandom( void ) return -1; } -#endif /* HB_OS_UNIX */ +#endif /* HB_OS_LINUX || HB_OS_UNIX */ static int arc4_seed_rand( void ) { @@ -455,68 +255,53 @@ static void arc4_seed( void ) ok = 1; #endif -#if defined( TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID ) - if( arc4_seed_proc_sys_kernel_random_uuid() == 0 ) - ok = 1; -#endif - -#if defined( TRY_SEED_SYSCTL_LINUX ) /* - * Apparently Linux is deprecating sysctl, and spewing warning - * messages when you try to use it. To avoid dmesg spamming, - * only try this if no previous method worked. + * If nothing else worked or hi ha cap mètode específic de seeding + * per a la plataforma actual, recorre a rand(). + * Si un mètode de plataforma específic existent tenia un + * (fallada transitòria, es tornarà a intentar en el següent + * cicle de seeding. */ - if( ! ok && arc4_seed_sysctl_linux() == 0 ) - ok = 1; -#endif + if( ! ok ) + arc4_seed_rand(); +} -#if defined( TRY_SEED_SYSCTL_BSD ) - if( arc4_seed_sysctl_bsd() == 0 ) - ok = 1; -#endif +static void arc4_stir( void ) +{ + int i; + + if( ! rs_initialized ) + { + arc4_init(); + rs_initialized = 1; + } + + arc4_seed(); /* - * If nothing else worked or there is no specific seeding - * method for the current platform, fall back to rand(). - * In case an existing platform-specific method had a - * (transient) failure, it will be re-tried at the next - * seeding cycle. + * Discard early keystream, as per recommendations in + * "Weaknesses in the Key Scheduling Algorithm of RC4" by + * Scott Fluhrer, Itsik Mantin, and Adi Shamir. + * https://web.archive.org/web/www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps + * + * Ilya Mironov's "(Not So) Random Shuffles of RC4" suggests that + * we drop at least 2*256 bytes, with 12*256 as a conservative + * value. + * + * RFC4345 says to drop 6*256. + * + * At least some versions of this code drop 4*256, in a mistaken + * belief that "words" in the Fluhrer/Mantin/Shamir paper refers + * to processor words. + * + * We add another sect to the cargo cult, and choose 12*256. */ - if( ! ok ) - arc4_seed_rand(); -} + for( i = 0; i < 12 * 256; i++ ) + ( void ) arc4_getbyte(); -static void arc4_stir(void) { - int i; - unsigned char rnd[128]; - - if (!rs_initialized) { - arc4_init(); - rs_initialized = 1; - } - - // Obtain entropy from /dev/urandom - int fd = open("/dev/urandom", O_RDONLY); - if (fd < 0) { - perror("open /dev/urandom"); - return; - } - if (read(fd, rnd, sizeof(rnd)) != sizeof(rnd)) { - perror("read /dev/urandom"); - close(fd); - return; - } - close(fd); - - for (i = 0; i < sizeof(rnd); i++) { - rs.s[i] = rnd[i]; - } - - rs.i = rs.j = 0; - arc4_count = 256; + arc4_count = BYTES_BEFORE_RESEED; } - static void arc4_stir_if_needed( void ) { #if defined( NO_PID_CHECK ) @@ -655,7 +440,7 @@ HB_U32 hb_arc4random_uniform( HB_U32 upper_bound ) } else { - /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ + /* (2**32 - (upper_bound * 2)) % upper_bound == 2**32 % upper_bound when upper_bound <= 2**31 */ min = ( ( 0xffffffff - ( upper_bound * 2 ) ) + 1 ) % upper_bound; } #endif From 7783cd4e9b47d6c6c51daf5665354e9de9dda265 Mon Sep 17 00:00:00 2001 From: endaco Date: Fri, 7 Jun 2024 15:02:50 +0200 Subject: [PATCH 6/7] src/rtl/arc4.c --- src/rtl/arc4.c | 303 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 262 insertions(+), 41 deletions(-) diff --git a/src/rtl/arc4.c b/src/rtl/arc4.c index 5969a7f254..fa3b11faed 100644 --- a/src/rtl/arc4.c +++ b/src/rtl/arc4.c @@ -48,11 +48,36 @@ #include "hbdate.h" #include "hbthread.h" +/* XXX: Check and possibly extend this to other Unix-like platforms */ +#if ( defined( HB_OS_BSD ) && ! defined( HB_OS_DARWIN ) ) || \ + ( defined( HB_OS_LINUX ) && \ + ! defined( HB_OS_ANDROID ) && \ + ! defined( __WATCOMC__ ) && \ + ! defined( __EMSCRIPTEN__ ) ) +# define HAVE_SYS_SYSCTL_H +# define HAVE_DECL_CTL_KERN +# define HAVE_DECL_KERN_RANDOM +# if defined( HB_OS_LINUX ) +# define HAVE_DECL_RANDOM_UUID +# endif +#endif + #if defined( HB_OS_WIN ) # include #elif defined( HB_OS_DOS ) || defined( HB_OS_OS2 ) # include #else +# if ! defined( __WATCOMC__ ) +# include +# endif +# include +# include +# ifdef HAVE_SYS_SYSCTL_H +# include +# if ! defined( HB_OS_LINUX ) && defined( KERN_ARND ) +# define HAVE_DECL_KERN_ARND +# endif +# endif # include # include #endif @@ -178,7 +203,182 @@ static int arc4_seed_win( void ) } #endif /* HB_OS_WIN */ -#if defined( HB_OS_LINUX ) || defined( HB_OS_UNIX ) +#if defined( HAVE_SYS_SYSCTL_H ) + +#if defined( HAVE_DECL_CTL_KERN ) && defined( HAVE_DECL_KERN_RANDOM ) && \ + defined( HAVE_DECL_RANDOM_UUID ) + +#define TRY_SEED_SYSCTL_LINUX +static int arc4_seed_sysctl_linux( void ) +{ + /* + * Based on code by William Ahern, this function tries to use the + * RANDOM_UUID sysctl to get entropy from the kernel. This can work + * even if /dev/urandom is inaccessible for some reason (e.g., we're + * running in a chroot). + */ + int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID }; + HB_U8 buf[ ADD_ENTROPY ]; + size_t len, n; + unsigned int i; + int any_set; + + memset( buf, 0, sizeof( buf ) ); + + for( len = 0; len < sizeof( buf ); len += n ) + { + n = sizeof( buf ) - len; + + if( sysctl( mib, 3, &buf[ len ], &n, NULL, 0 ) != 0 ) + return -1; + } + + /* make sure that the buffer actually got set. */ + for( i = 0, any_set = 0; i < sizeof( buf ); ++i ) + any_set |= buf[ i ]; + + if( ! any_set ) + return -1; + + arc4_addrandom( buf, sizeof( buf ) ); + memset( buf, 0, sizeof( buf ) ); + + return 0; +} +#endif /* HAVE_DECL_CTL_KERN && HAVE_DECL_KERN_RANDOM && HAVE_DECL_RANDOM_UUID */ + +#if defined( HAVE_DECL_CTL_KERN ) && defined( HAVE_DECL_KERN_ARND ) + +#define TRY_SEED_SYSCTL_BSD +static int arc4_seed_sysctl_bsd( void ) +{ + /* + * Based on code from William Ahern and from OpenBSD, this function + * tries to use the KERN_ARND syscall to get entropy from the kernel. + * This can work even if /dev/urandom is inaccessible for some reason + * (e.g., we're running in a chroot). + */ + int mib[] = { CTL_KERN, KERN_ARND }; + HB_U8 buf[ ADD_ENTROPY ]; + size_t len, n; + int i, any_set; + + memset( buf, 0, sizeof( buf ) ); + + len = sizeof( buf ); + if( sysctl( mib, 2, buf, &len, NULL, 0 ) == -1 ) + { + for( len = 0; len < sizeof( buf ); len += sizeof( unsigned ) ) + { + n = sizeof( unsigned ); + + if( n + len > sizeof( buf ) ) + n = len - sizeof( buf ); + + if( sysctl( mib, 2, &buf[ len ], &n, NULL, 0 ) == -1 ) + return -1; + } + } + + /* make sure that the buffer actually got set. */ + for( i = any_set = 0; i < ( int ) sizeof( buf ); ++i ) + any_set |= buf[ i ]; + + if( ! any_set ) + return -1; + + arc4_addrandom( buf, sizeof( buf ) ); + memset( buf, 0, sizeof( buf ) ); + + return 0; +} +#endif /* HAVE_DECL_CTL_KERN && HAVE_DECL_KERN_ARND */ + +#endif /* defined( HAVE_SYS_SYSCTL_H ) */ + +#if defined( HB_OS_LINUX ) + +#define TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID +static _HB_INLINE_ int hex_char_to_int( char c ) +{ + switch( c ) + { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + case 'A': case 'a': return 10; + case 'B': case 'b': return 11; + case 'C': case 'c': return 12; + case 'D': case 'd': return 13; + case 'E': case 'e': return 14; + case 'F': case 'f': return 15; + } + + return -1; +} + +static int arc4_seed_proc_sys_kernel_random_uuid( void ) +{ + /* + * Occasionally, somebody will make /proc/sys accessible in a chroot, + * but not /dev/urandom. Let's try /proc/sys/kernel/random/uuid. + * Its format is stupid, so we need to decode it from hex. + */ + char buf[ 128 ]; + HB_U8 entropy[ 64 ]; + int bytes, i, nybbles; + + for( bytes = 0; bytes < ADD_ENTROPY; ) + { + int fd = open( "/proc/sys/kernel/random/uuid", O_RDONLY, 0 ); + int n; + + if( fd < 0 ) + return -1; + + n = read( fd, buf, sizeof( buf ) ); + close( fd ); + + if( n <= 0 ) + return -1; + + memset( entropy, 0, sizeof( entropy ) ); + for( i = nybbles = 0; i < n; ++i ) + { + if( HB_ISXDIGIT( buf[ i ] ) ) + { + int nyb = hex_char_to_int( buf[ i ] ); + + if( nybbles & 1 ) + entropy[ nybbles / 2 ] |= nyb; + else + entropy[ nybbles / 2 ] |= nyb << 4; + + ++nybbles; + } + } + if( nybbles < 2 ) + return -1; + + arc4_addrandom( entropy, nybbles / 2 ); + bytes += nybbles / 2; + } + + memset( entropy, 0, sizeof( entropy ) ); + memset( buf, 0, sizeof( buf ) ); + + return 0; +} +#endif /* HB_OS_LINUX */ + +#if defined( HB_OS_UNIX ) #define TRY_SEED_URANDOM static int arc4_seed_urandom( void ) @@ -217,7 +417,7 @@ static int arc4_seed_urandom( void ) return -1; } -#endif /* HB_OS_LINUX || HB_OS_UNIX */ +#endif /* HB_OS_UNIX */ static int arc4_seed_rand( void ) { @@ -255,53 +455,68 @@ static void arc4_seed( void ) ok = 1; #endif +#if defined( TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID ) + if( arc4_seed_proc_sys_kernel_random_uuid() == 0 ) + ok = 1; +#endif + +#if defined( TRY_SEED_SYSCTL_LINUX ) /* - * If nothing else worked or hi ha cap mètode específic de seeding - * per a la plataforma actual, recorre a rand(). - * Si un mètode de plataforma específic existent tenia un - * (fallada transitòria, es tornarà a intentar en el següent - * cicle de seeding. + * Apparently Linux is deprecating sysctl, and spewing warning + * messages when you try to use it. To avoid dmesg spamming, + * only try this if no previous method worked. */ - if( ! ok ) - arc4_seed_rand(); -} - -static void arc4_stir( void ) -{ - int i; - - if( ! rs_initialized ) - { - arc4_init(); - rs_initialized = 1; - } + if( ! ok && arc4_seed_sysctl_linux() == 0 ) + ok = 1; +#endif - arc4_seed(); +#if defined( TRY_SEED_SYSCTL_BSD ) + if( arc4_seed_sysctl_bsd() == 0 ) + ok = 1; +#endif /* - * Discard early keystream, as per recommendations in - * "Weaknesses in the Key Scheduling Algorithm of RC4" by - * Scott Fluhrer, Itsik Mantin, and Adi Shamir. - * https://web.archive.org/web/www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps - * - * Ilya Mironov's "(Not So) Random Shuffles of RC4" suggests that - * we drop at least 2*256 bytes, with 12*256 as a conservative - * value. - * - * RFC4345 says to drop 6*256. - * - * At least some versions of this code drop 4*256, in a mistaken - * belief that "words" in the Fluhrer/Mantin/Shamir paper refers - * to processor words. - * - * We add another sect to the cargo cult, and choose 12*256. + * If nothing else worked or there is no specific seeding + * method for the current platform, fall back to rand(). + * In case an existing platform-specific method had a + * (transient) failure, it will be re-tried at the next + * seeding cycle. */ - for( i = 0; i < 12 * 256; i++ ) - ( void ) arc4_getbyte(); + if( ! ok ) + arc4_seed_rand(); +} - arc4_count = BYTES_BEFORE_RESEED; +static void arc4_stir(void) { + int i; + unsigned char rnd[128]; + + if (!rs_initialized) { + arc4_init(); + rs_initialized = 1; + } + + // Obtain entropy from /dev/urandom + int fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) { + perror("open /dev/urandom"); + return; + } + if (read(fd, rnd, sizeof(rnd)) != sizeof(rnd)) { + perror("read /dev/urandom"); + close(fd); + return; + } + close(fd); + + for (i = 0; i < sizeof(rnd); i++) { + rs.s[i] = rnd[i]; + } + + rs.i = rs.j = 0; + arc4_count = 256; } + static void arc4_stir_if_needed( void ) { #if defined( NO_PID_CHECK ) @@ -440,7 +655,7 @@ HB_U32 hb_arc4random_uniform( HB_U32 upper_bound ) } else { - /* (2**32 - (upper_bound * 2)) % upper_bound == 2**32 % upper_bound when upper_bound <= 2**31 */ + /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ min = ( ( 0xffffffff - ( upper_bound * 2 ) ) + 1 ) % upper_bound; } #endif @@ -460,3 +675,9 @@ HB_U32 hb_arc4random_uniform( HB_U32 upper_bound ) return r % upper_bound; } + +HB_FUNC( HB_ARC4RANDOM ) +{ + hb_retni( hb_arc4random() ); +} + From 8aebc73491f47117cb3d9053254435d8a740bf72 Mon Sep 17 00:00:00 2001 From: endaco Date: Fri, 7 Jun 2024 16:42:50 +0200 Subject: [PATCH 7/7] modificat: src/rtl/arc4.c --- src/rtl/arc4.c | 298 +++++++------------------------------------------ 1 file changed, 41 insertions(+), 257 deletions(-) diff --git a/src/rtl/arc4.c b/src/rtl/arc4.c index fa3b11faed..703649e2c3 100644 --- a/src/rtl/arc4.c +++ b/src/rtl/arc4.c @@ -48,36 +48,11 @@ #include "hbdate.h" #include "hbthread.h" -/* XXX: Check and possibly extend this to other Unix-like platforms */ -#if ( defined( HB_OS_BSD ) && ! defined( HB_OS_DARWIN ) ) || \ - ( defined( HB_OS_LINUX ) && \ - ! defined( HB_OS_ANDROID ) && \ - ! defined( __WATCOMC__ ) && \ - ! defined( __EMSCRIPTEN__ ) ) -# define HAVE_SYS_SYSCTL_H -# define HAVE_DECL_CTL_KERN -# define HAVE_DECL_KERN_RANDOM -# if defined( HB_OS_LINUX ) -# define HAVE_DECL_RANDOM_UUID -# endif -#endif - #if defined( HB_OS_WIN ) # include #elif defined( HB_OS_DOS ) || defined( HB_OS_OS2 ) # include #else -# if ! defined( __WATCOMC__ ) -# include -# endif -# include -# include -# ifdef HAVE_SYS_SYSCTL_H -# include -# if ! defined( HB_OS_LINUX ) && defined( KERN_ARND ) -# define HAVE_DECL_KERN_ARND -# endif -# endif # include # include #endif @@ -203,182 +178,7 @@ static int arc4_seed_win( void ) } #endif /* HB_OS_WIN */ -#if defined( HAVE_SYS_SYSCTL_H ) - -#if defined( HAVE_DECL_CTL_KERN ) && defined( HAVE_DECL_KERN_RANDOM ) && \ - defined( HAVE_DECL_RANDOM_UUID ) - -#define TRY_SEED_SYSCTL_LINUX -static int arc4_seed_sysctl_linux( void ) -{ - /* - * Based on code by William Ahern, this function tries to use the - * RANDOM_UUID sysctl to get entropy from the kernel. This can work - * even if /dev/urandom is inaccessible for some reason (e.g., we're - * running in a chroot). - */ - int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID }; - HB_U8 buf[ ADD_ENTROPY ]; - size_t len, n; - unsigned int i; - int any_set; - - memset( buf, 0, sizeof( buf ) ); - - for( len = 0; len < sizeof( buf ); len += n ) - { - n = sizeof( buf ) - len; - - if( sysctl( mib, 3, &buf[ len ], &n, NULL, 0 ) != 0 ) - return -1; - } - - /* make sure that the buffer actually got set. */ - for( i = 0, any_set = 0; i < sizeof( buf ); ++i ) - any_set |= buf[ i ]; - - if( ! any_set ) - return -1; - - arc4_addrandom( buf, sizeof( buf ) ); - memset( buf, 0, sizeof( buf ) ); - - return 0; -} -#endif /* HAVE_DECL_CTL_KERN && HAVE_DECL_KERN_RANDOM && HAVE_DECL_RANDOM_UUID */ - -#if defined( HAVE_DECL_CTL_KERN ) && defined( HAVE_DECL_KERN_ARND ) - -#define TRY_SEED_SYSCTL_BSD -static int arc4_seed_sysctl_bsd( void ) -{ - /* - * Based on code from William Ahern and from OpenBSD, this function - * tries to use the KERN_ARND syscall to get entropy from the kernel. - * This can work even if /dev/urandom is inaccessible for some reason - * (e.g., we're running in a chroot). - */ - int mib[] = { CTL_KERN, KERN_ARND }; - HB_U8 buf[ ADD_ENTROPY ]; - size_t len, n; - int i, any_set; - - memset( buf, 0, sizeof( buf ) ); - - len = sizeof( buf ); - if( sysctl( mib, 2, buf, &len, NULL, 0 ) == -1 ) - { - for( len = 0; len < sizeof( buf ); len += sizeof( unsigned ) ) - { - n = sizeof( unsigned ); - - if( n + len > sizeof( buf ) ) - n = len - sizeof( buf ); - - if( sysctl( mib, 2, &buf[ len ], &n, NULL, 0 ) == -1 ) - return -1; - } - } - - /* make sure that the buffer actually got set. */ - for( i = any_set = 0; i < ( int ) sizeof( buf ); ++i ) - any_set |= buf[ i ]; - - if( ! any_set ) - return -1; - - arc4_addrandom( buf, sizeof( buf ) ); - memset( buf, 0, sizeof( buf ) ); - - return 0; -} -#endif /* HAVE_DECL_CTL_KERN && HAVE_DECL_KERN_ARND */ - -#endif /* defined( HAVE_SYS_SYSCTL_H ) */ - -#if defined( HB_OS_LINUX ) - -#define TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID -static _HB_INLINE_ int hex_char_to_int( char c ) -{ - switch( c ) - { - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; - case 'A': case 'a': return 10; - case 'B': case 'b': return 11; - case 'C': case 'c': return 12; - case 'D': case 'd': return 13; - case 'E': case 'e': return 14; - case 'F': case 'f': return 15; - } - - return -1; -} - -static int arc4_seed_proc_sys_kernel_random_uuid( void ) -{ - /* - * Occasionally, somebody will make /proc/sys accessible in a chroot, - * but not /dev/urandom. Let's try /proc/sys/kernel/random/uuid. - * Its format is stupid, so we need to decode it from hex. - */ - char buf[ 128 ]; - HB_U8 entropy[ 64 ]; - int bytes, i, nybbles; - - for( bytes = 0; bytes < ADD_ENTROPY; ) - { - int fd = open( "/proc/sys/kernel/random/uuid", O_RDONLY, 0 ); - int n; - - if( fd < 0 ) - return -1; - - n = read( fd, buf, sizeof( buf ) ); - close( fd ); - - if( n <= 0 ) - return -1; - - memset( entropy, 0, sizeof( entropy ) ); - for( i = nybbles = 0; i < n; ++i ) - { - if( HB_ISXDIGIT( buf[ i ] ) ) - { - int nyb = hex_char_to_int( buf[ i ] ); - - if( nybbles & 1 ) - entropy[ nybbles / 2 ] |= nyb; - else - entropy[ nybbles / 2 ] |= nyb << 4; - - ++nybbles; - } - } - if( nybbles < 2 ) - return -1; - - arc4_addrandom( entropy, nybbles / 2 ); - bytes += nybbles / 2; - } - - memset( entropy, 0, sizeof( entropy ) ); - memset( buf, 0, sizeof( buf ) ); - - return 0; -} -#endif /* HB_OS_LINUX */ - -#if defined( HB_OS_UNIX ) +#if defined( HB_OS_LINUX ) || defined( HB_OS_UNIX ) #define TRY_SEED_URANDOM static int arc4_seed_urandom( void ) @@ -417,7 +217,7 @@ static int arc4_seed_urandom( void ) return -1; } -#endif /* HB_OS_UNIX */ +#endif /* HB_OS_LINUX || HB_OS_UNIX */ static int arc4_seed_rand( void ) { @@ -455,68 +255,53 @@ static void arc4_seed( void ) ok = 1; #endif -#if defined( TRY_SEED_PROC_SYS_KERNEL_RANDOM_UUID ) - if( arc4_seed_proc_sys_kernel_random_uuid() == 0 ) - ok = 1; -#endif - -#if defined( TRY_SEED_SYSCTL_LINUX ) /* - * Apparently Linux is deprecating sysctl, and spewing warning - * messages when you try to use it. To avoid dmesg spamming, - * only try this if no previous method worked. + * If nothing else worked or hi ha cap mètode específic de seeding + * per a la plataforma actual, recorre a rand(). + * Si un mètode de plataforma específic existent tenia un + * (fallada transitòria, es tornarà a intentar en el següent + * cicle de seeding. */ - if( ! ok && arc4_seed_sysctl_linux() == 0 ) - ok = 1; -#endif + if( ! ok ) + arc4_seed_rand(); +} -#if defined( TRY_SEED_SYSCTL_BSD ) - if( arc4_seed_sysctl_bsd() == 0 ) - ok = 1; -#endif +static void arc4_stir( void ) +{ + int i; + + if( ! rs_initialized ) + { + arc4_init(); + rs_initialized = 1; + } + + arc4_seed(); /* - * If nothing else worked or there is no specific seeding - * method for the current platform, fall back to rand(). - * In case an existing platform-specific method had a - * (transient) failure, it will be re-tried at the next - * seeding cycle. + * Discard early keystream, as per recommendations in + * "Weaknesses in the Key Scheduling Algorithm of RC4" by + * Scott Fluhrer, Itsik Mantin, and Adi Shamir. + * https://web.archive.org/web/www.wisdom.weizmann.ac.il/~itsik/RC4/Papers/Rc4_ksa.ps + * + * Ilya Mironov's "(Not So) Random Shuffles of RC4" suggests that + * we drop at least 2*256 bytes, with 12*256 as a conservative + * value. + * + * RFC4345 says to drop 6*256. + * + * At least some versions of this code drop 4*256, in a mistaken + * belief that "words" in the Fluhrer/Mantin/Shamir paper refers + * to processor words. + * + * We add another sect to the cargo cult, and choose 12*256. */ - if( ! ok ) - arc4_seed_rand(); -} + for( i = 0; i < 12 * 256; i++ ) + ( void ) arc4_getbyte(); -static void arc4_stir(void) { - int i; - unsigned char rnd[128]; - - if (!rs_initialized) { - arc4_init(); - rs_initialized = 1; - } - - // Obtain entropy from /dev/urandom - int fd = open("/dev/urandom", O_RDONLY); - if (fd < 0) { - perror("open /dev/urandom"); - return; - } - if (read(fd, rnd, sizeof(rnd)) != sizeof(rnd)) { - perror("read /dev/urandom"); - close(fd); - return; - } - close(fd); - - for (i = 0; i < sizeof(rnd); i++) { - rs.s[i] = rnd[i]; - } - - rs.i = rs.j = 0; - arc4_count = 256; + arc4_count = BYTES_BEFORE_RESEED; } - static void arc4_stir_if_needed( void ) { #if defined( NO_PID_CHECK ) @@ -655,7 +440,7 @@ HB_U32 hb_arc4random_uniform( HB_U32 upper_bound ) } else { - /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ + /* (2**32 - (upper_bound * 2)) % upper_bound == 2**32 % upper_bound when upper_bound <= 2**31 */ min = ( ( 0xffffffff - ( upper_bound * 2 ) ) + 1 ) % upper_bound; } #endif @@ -680,4 +465,3 @@ HB_FUNC( HB_ARC4RANDOM ) { hb_retni( hb_arc4random() ); } -