diff --git a/ChangeLog b/ChangeLog index 094801504..9c9c59d46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-11-19 Richard Frith-Macdonald + + * configure.ac: Changes to tolerate older version of gnutls + * configure: regenerate + * config/pathtls.m4: Fix typos + * Headers/Additions/GNUstepBase/config.h.in: regenerate + * Source/GSSocketStream.m: Fix to send required events to handler + after SSL or SOCKS module has dealt with them. + * Source/GSStream.h: New method to reset sent events mask + * Source/GSStream.m: ditto + 2008-11-18 Richard Frith-Macdonald * Source/NSURL.m: Check class of arguments to designated initialiser diff --git a/Headers/Additions/GNUstepBase/config.h.in b/Headers/Additions/GNUstepBase/config.h.in index ff960743e..eb2890246 100644 --- a/Headers/Additions/GNUstepBase/config.h.in +++ b/Headers/Additions/GNUstepBase/config.h.in @@ -250,6 +250,9 @@ /* Define if libgnutls available */ #undef HAVE_GNUTLS +/* Define to 1 if you have the `gnutls_transport_set_errno' function. */ +#undef HAVE_GNUTLS_TRANSPORT_SET_ERRNO + /* Define to 1 if you have the header file. */ #undef HAVE_GRP_H diff --git a/Source/GSSocketStream.m b/Source/GSSocketStream.m index 49a44e04b..a41707dac 100644 --- a/Source/GSSocketStream.m +++ b/Source/GSSocketStream.m @@ -236,7 +236,11 @@ GSTLSPull(gnutls_transport_ptr_t handle, void *buffer, size_t len) { e = EAGAIN; // Tell GNUTLS this would block. } +#if HAVE_GNUTLS_TRANSPORT_SET_ERRNO gnutls_transport_set_errno (tls->session, e); +#else + errno = e; // Not thread-safe +#endif } return result; } @@ -263,7 +267,12 @@ GSTLSPush(gnutls_transport_ptr_t handle, const void *buffer, size_t len) { e = EAGAIN; // Tell GNUTLS this would block. } +#if HAVE_GNUTLS_TRANSPORT_SET_ERRNO gnutls_transport_set_errno (tls->session, e); +#else + errno = e; // Not thread-safe +#endif + } return result; } @@ -383,7 +392,6 @@ static gnutls_anon_client_credentials_t anoncred; handshake = NO; // Handshake is now complete. active = YES; // The TLS session is now active. } - } } @@ -458,7 +466,9 @@ static gnutls_anon_client_credentials_t anoncred; if ([proto isEqualToString: NSStreamSocketSecurityLevelTLSv1] == YES) { const int proto_prio[4] = { +#if defined(GNUTLS_TLS1_2) GNUTLS_TLS1_2, +#endif GNUTLS_TLS1_1, GNUTLS_TLS1_0, 0 }; @@ -534,19 +544,24 @@ static gnutls_anon_client_credentials_t anoncred; @"GSTLS completed on %p", stream); if ([istream streamStatus] == NSStreamStatusOpen) { + [istream _resetEvents: NSStreamEventOpenCompleted]; [istream _sendEvent: NSStreamEventOpenCompleted]; } else { + [istream _resetEvents: NSStreamEventErrorOccurred]; [istream _sendEvent: NSStreamEventErrorOccurred]; } if ([ostream streamStatus] == NSStreamStatusOpen) { + [ostream _resetEvents: NSStreamEventOpenCompleted + | NSStreamEventHasSpaceAvailable]; [ostream _sendEvent: NSStreamEventOpenCompleted]; [ostream _sendEvent: NSStreamEventHasSpaceAvailable]; } else { + [ostream _resetEvents: NSStreamEventErrorOccurred]; [ostream _sendEvent: NSStreamEventErrorOccurred]; } } @@ -704,19 +719,24 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn"; [GSTLS tryInput: is output: os]; if ([is streamStatus] == NSStreamStatusOpen) { + [is _resetEvents: NSStreamEventOpenCompleted]; [is _sendEvent: NSStreamEventOpenCompleted]; } else { + [is _resetEvents: NSStreamEventErrorOccurred]; [is _sendEvent: NSStreamEventErrorOccurred]; } if ([os streamStatus] == NSStreamStatusOpen) { + [os _resetEvents: NSStreamEventOpenCompleted + | NSStreamEventHasSpaceAvailable]; [os _sendEvent: NSStreamEventOpenCompleted]; [os _sendEvent: NSStreamEventHasSpaceAvailable]; } else { + [os _resetEvents: NSStreamEventErrorOccurred]; [os _sendEvent: NSStreamEventErrorOccurred]; } RELEASE(is); diff --git a/Source/GSStream.h b/Source/GSStream.h index 89b5daba2..a82e3b40c 100644 --- a/Source/GSStream.h +++ b/Source/GSStream.h @@ -112,6 +112,10 @@ IVARS */ - (void*) _loopID; +/** Reset events in mask to allow them to be sent again. + */ +- (void) _resetEvents: (int)mask; + /** * Place the stream in all the scheduled runloops. */ diff --git a/Source/GSStream.m b/Source/GSStream.m index d9dd9b966..7b7406b09 100644 --- a/Source/GSStream.m +++ b/Source/GSStream.m @@ -337,6 +337,11 @@ static RunLoopEventType typeForStream(NSStream *aStream) return; } +- (void) _resetEvents: (int)mask +{ + return; +} + - (void) _schedule { } @@ -393,6 +398,11 @@ static RunLoopEventType typeForStream(NSStream *aStream) _currentStatus = NSStreamStatusError; } +- (void) _resetEvents: (int)mask +{ + _events &= ~mask; +} + - (void) _schedule { NSMapEnumerator enumerator; diff --git a/config/pathtls.m4 b/config/pathtls.m4 index 1bdb15666..903052236 100644 --- a/config/pathtls.m4 +++ b/config/pathtls.m4 @@ -52,8 +52,8 @@ main() printf("*** You need a version of libtgnuls newer than $min_tls_version.\n"); printf("*** If you have already installed a sufficiently new version, this error\n"); printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n"); - printf("*** being found. Yoiu can fix this is by removing the old version\n"); - printf("*** of libgnutlsthe\n"); + printf("*** being found. You can fix this is by removing the old version\n"); + printf("*** of libgnutls.\n"); return 1; } return 0; @@ -100,8 +100,8 @@ main() printf("*** You need a version of libtgnuls newer than $min_tls_version.\n"); printf("*** If you have already installed a sufficiently new version, this error\n"); printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n"); - printf("*** being found. Yoiu can fix this is by removing the old version\n"); - printf("*** of libgnutlsthe\n"); + printf("*** being found. You can fix this is by removing the old version\n"); + printf("*** of libgnutls.\n"); return 1; } return 0; diff --git a/configure b/configure index 4a9c79643..5cb1cfc9d 100755 --- a/configure +++ b/configure @@ -18264,6 +18264,7 @@ if test $enable_tls = yes; then saved_LIBS="$LIBS" saved_CFLAGS="$CFLAGS" +# AM_PATH_TLS(2.0.1, enable_libgnutls=yes, enable_libgnutls=no) # Check whether --with-tls-prefix or --without-tls-prefix was given. @@ -18328,7 +18329,7 @@ else echo "${ECHO_T}no" >&6 fi - min_tls_version=2.0.1 + min_tls_version=1.4.0 echo "$as_me:$LINENO: checking for libgnutls - version >= $min_tls_version" >&5 echo $ECHO_N "checking for libgnutls - version >= $min_tls_version... $ECHO_C" >&6 no_tls="" @@ -18367,8 +18368,8 @@ main() printf("*** You need a version of libtgnuls newer than $min_tls_version.\n"); printf("*** If you have already installed a sufficiently new version, this error\n"); printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n"); - printf("*** being found. Yoiu can fix this is by removing the old version\n"); - printf("*** of libgnutlsthe\n"); + printf("*** being found. You can fix this is by removing the old version\n"); + printf("*** of libgnutls.\n"); return 1; } return 0; @@ -18444,8 +18445,8 @@ main() printf("*** You need a version of libtgnuls newer than $min_tls_version.\n"); printf("*** If you have already installed a sufficiently new version, this error\n"); printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n"); - printf("*** being found. Yoiu can fix this is by removing the old version\n"); - printf("*** of libgnutlsthe\n"); + printf("*** being found. You can fix this is by removing the old version\n"); + printf("*** of libgnutls.\n"); return 1; } return 0; @@ -18519,6 +18520,112 @@ cat >>confdefs.h <<\_ACEOF #define HAVE_GNUTLS 1 _ACEOF + +for ac_func in gnutls_transport_set_errno +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + if test "$ac_cv_func_gnutls_transport_set_errno" = "no"; then + { echo "$as_me:$LINENO: WARNING: Missing support for thread-safe error handling in GNUTLS. Please check that you have the most recent version installed (2.0 or later chould be fine)." >&5 +echo "$as_me: WARNING: Missing support for thread-safe error handling in GNUTLS. Please check that you have the most recent version installed (2.0 or later chould be fine)." >&2;} + fi else HAVE_GNUTLS=0 # Restore the CFLAGS and LIBS because AM_PATH_TLS messes them diff --git a/configure.ac b/configure.ac index 59ed3d62c..8d39cabfb 100644 --- a/configure.ac +++ b/configure.ac @@ -2217,13 +2217,18 @@ if test $enable_tls = yes; then saved_LIBS="$LIBS" saved_CFLAGS="$CFLAGS" - AM_PATH_TLS(2.0.1, enable_libgnutls=yes, enable_libgnutls=no) +# AM_PATH_TLS(2.0.1, enable_libgnutls=yes, enable_libgnutls=no) + AM_PATH_TLS(1.4.0, enable_libgnutls=yes, enable_libgnutls=no) if test $enable_libgnutls = yes; then CPPFLAGS="$CPPFLAGS $TLS_CFLAGS" INCLUDE_FLAGS="$INCLUDE_FLAGS $TLS_CFLAGS" LIBS="$TLS_LIBS $LIBS" HAVE_GNUTLS=1 AC_DEFINE(HAVE_GNUTLS,1,[Define if libgnutls available]) + AC_CHECK_FUNCS(gnutls_transport_set_errno) + if test "$ac_cv_func_gnutls_transport_set_errno" = "no"; then + AC_MSG_WARN([Missing support for thread-safe error handling in GNUTLS. Please check that you have the most recent version installed (2.0 or later chould be fine).]) + fi else HAVE_GNUTLS=0 # Restore the CFLAGS and LIBS because AM_PATH_TLS messes them