From f506e19e152e070f04574ad67e282af8691606f5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 17 Oct 2011 12:30:51 -0500 Subject: [PATCH] FS-3471 making this the new default and patching libdingaling to use it exclusively with openssl, now we actually have single thread for gtalk an no gah noodlez --- libs/iksemel/INSTALL | 241 ++++++++++++++---- libs/iksemel/configure.ac | 5 +- libs/iksemel/openssl.m4 | 49 ++++ libs/iksemel/src/stream.c | 214 ++++++++++++++++ libs/libdingaling/src/libdingaling.c | 89 ++----- libs/libdingaling/src/libdingaling.h | 6 +- libs/win32/iksemel/iksemel.2008.vcproj | 126 ++++----- libs/win32/iksemel/iksemel.2010.vcxproj | 16 +- .../mod_dingaling/mod_dingaling.2010.vcxproj | 6 + .../endpoints/mod_dingaling/mod_dingaling.c | 30 ++- 10 files changed, 573 insertions(+), 209 deletions(-) create mode 100644 libs/iksemel/openssl.m4 diff --git a/libs/iksemel/INSTALL b/libs/iksemel/INSTALL index 23e5f25d0e..7d1c323bea 100644 --- a/libs/iksemel/INSTALL +++ b/libs/iksemel/INSTALL @@ -1,16 +1,25 @@ Installation Instructions ************************* -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free -Software Foundation, Inc. +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. Basic Installation ================== -These are generic installation instructions. + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -23,9 +32,9 @@ debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is +the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale -cache files.) +cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail @@ -35,30 +44,37 @@ some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. -The simplest way to compile this package is: + The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. + `./configure' to configure the package for your system. - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with - the package. + the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and - documentation. + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. - 5. You can remove the program binaries and object files from the + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is @@ -67,45 +83,69 @@ The simplest way to compile this package is: all sorts of other programs in order to regenerate files that came with the distribution. + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + Compilers and Options ===================== -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== -You can compile the package for more than one kind of computer at the + You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the +own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. Installation Names ================== -By default, `make install' installs the package's commands under + By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you @@ -116,16 +156,47 @@ Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to + Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The @@ -137,14 +208,53 @@ find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + Specifying the System Type ========================== -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: @@ -152,7 +262,8 @@ type, such as `sun4', or a canonical name which has the form: where SYSTEM can have one of these forms: - OS KERNEL-OS + OS + KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't @@ -170,9 +281,9 @@ eventually be run) with `--host=TYPE'. Sharing Defaults ================ -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. @@ -181,7 +292,7 @@ A warning: not all `configure' scripts look for a site script. Defining Variables ================== -Variables not defined in a site shell script can be set in the + Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set @@ -190,21 +301,29 @@ them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). Here is a another example: +overridden in the site shell script). - /bin/bash ./configure CONFIG_SHELL=/bin/bash +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: -Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent -configuration-related scripts to be executed by `/bin/bash'. + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== -`configure' recognizes the following options to control how it operates. + `configure' recognizes the following options to control how it +operates. `--help' `-h' - Print a summary of the options to `configure', and exit. + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. `--version' `-V' @@ -231,6 +350,16 @@ configuration-related scripts to be executed by `/bin/bash'. Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. diff --git a/libs/iksemel/configure.ac b/libs/iksemel/configure.ac index 403725a80d..4d6ab91eb8 100644 --- a/libs/iksemel/configure.ac +++ b/libs/iksemel/configure.ac @@ -50,7 +50,10 @@ AC_SEARCH_LIBS(recv,socket) AC_CHECK_FUNCS(getopt_long) AC_CHECK_FUNCS(getaddrinfo) -AX_PATH_LIBGNUTLS(,AC_DEFINE(HAVE_GNUTLS,,"Use libgnutls")) +#AX_PATH_LIBGNUTLS(,AC_DEFINE(HAVE_GNUTLS,,"Use libgnutls")) + +m4_include([openssl.m4]) +SAC_OPENSSL dnl Check -Wall flag of GCC if test "x$GCC" = "xyes"; then diff --git a/libs/iksemel/openssl.m4 b/libs/iksemel/openssl.m4 new file mode 100644 index 0000000000..8adea2192e --- /dev/null +++ b/libs/iksemel/openssl.m4 @@ -0,0 +1,49 @@ +dnl ====================================================================== +dnl SAC_OPENSSL +dnl ====================================================================== +AC_DEFUN([SAC_OPENSSL], [ + +AC_ARG_WITH(openssl, +[ --with-openssl use OpenSSL [[enabled]]],, with_openssl=pkg-config) + +dnl SOSXXX:SAC_ASSERT_DEF([openssl libraries]) + + +if test "$with_openssl" = no ;then + : # No openssl +else + + if test "$with_openssl" = "pkg-config" ; then + PKG_CHECK_MODULES(openssl, openssl, + [HAVE_TLS=1 HAVE_SSL=1 LIBS="$openssl_LIBS $LIBS"], + [HAVE_SSL=0]) + fi + + if test x$HAVE_SSL = x1 ; then + AC_DEFINE([HAVE_LIBCRYPTO], 1, [Define to 1 if you have the `crypto' library (-lcrypto).]) + AC_DEFINE([HAVE_LIBSSL], 1, [Define to 1 if you have the `ssl' library (-lssl).]) + else + AC_CHECK_HEADERS([openssl/tls1.h], [ + HAVE_SSL=1 HAVE_TLS=1 + + AC_CHECK_LIB(crypto, BIO_new,, + HAVE_SSL=0 + AC_MSG_WARN(OpenSSL crypto library was not found)) + + AC_CHECK_LIB(ssl, TLSv1_method,, + HAVE_TLS=0 + AC_MSG_WARN(OpenSSL protocol library was not found)) + ],[AC_MSG_WARN(OpenSSL include files were not found)]) + fi + + if test x$HAVE_SSL = x1; then + AC_DEFINE([HAVE_SSL], 1, [Define to 1 if you have OpenSSL]) + fi + + if test x$HAVE_TLS = x1; then + AC_DEFINE([HAVE_TLS], 1, [Define to 1 if you have TLS]) + fi +fi + +AM_CONDITIONAL(HAVE_TLS, test x$HAVE_TLS = x1) +]) diff --git a/libs/iksemel/src/stream.c b/libs/iksemel/src/stream.c index a7e57cb236..a1a4494e59 100644 --- a/libs/iksemel/src/stream.c +++ b/libs/iksemel/src/stream.c @@ -19,6 +19,19 @@ #include #endif +#ifdef HAVE_SSL +#include +#include +#ifdef WIN32 +typedef unsigned __int32 uint32_t; +#else +#ifdef HAVE_SYS_SELECT_H +#include +#endif +#include +#endif +#endif + #define SF_FOREIGN 1 #define SF_TRY_SECURE 2 #define SF_SECURE 4 @@ -41,9 +54,63 @@ struct stream_data { #ifdef HAVE_GNUTLS gnutls_session sess; gnutls_certificate_credentials cred; +#elif HAVE_SSL + SSL* ssl; + SSL_CTX* ssl_ctx; #endif }; +#ifdef HAVE_SSL +#ifdef WIN32 +static int sock_read_ready(struct stream_data *data, uint32_t ms) +{ + int r = 0; + fd_set fds; + struct timeval tv; + + FD_ZERO(&fds); + +#ifdef WIN32 +#pragma warning( push ) +#pragma warning( disable : 4127 ) + FD_SET(SSL_get_fd(data->ssl), &fds); +#pragma warning( pop ) +#else + FD_SET(SSL_get_fd(data->ssl), &fds); +#endif + + tv.tv_sec = ms / 1000; + tv.tv_usec = (ms % 1000) * ms; + + r = select (SSL_get_fd(data->ssl) + 1, &fds, NULL, NULL, &tv); + + return r; +} +#else +static int sock_read_ready(struct stream_data *data, int ms) +{ + struct pollfd pfds[2] = { { 0 } }; + int s = 0, r = 0; + + pfds[0].fd = SSL_get_fd(data->ssl); + pfds[0].events |= POLLIN; + + s = poll(pfds, 1, ms); + + + if (s < 0) { + r = s; + } else if (s > 0) { + if ((pfds[0].revents & POLLIN)) { + r = 1; + } + } + + return r; +} +#endif +#endif + #ifdef HAVE_GNUTLS #ifndef WIN32 #include @@ -120,6 +187,86 @@ handshake (struct stream_data *data) iks_send_header (data->prs, data->server); return IKS_OK; +} // HAVE_GNUTLS +#elif HAVE_SSL +static int wait_for_data(struct stream_data *data, int ret, int timeout) +{ + struct timeval tv; + fd_set fds; + int err; + int retval = IKS_OK; + + err = SSL_get_error(data->ssl, ret); + + switch(err) + { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + ret = sock_read_ready(data, timeout*1000); + + if (ret == -1) { + retval = IKS_NET_TLSFAIL; + } + + break; + default: + if(data->logHook) + data->logHook(data->user_data, ERR_error_string(err, NULL), strlen(ERR_error_string(err, NULL)), 1); + retval = IKS_NET_TLSFAIL; + break; + } + + ERR_clear_error(); + + return retval; +} + +static int +handshake (struct stream_data *data) +{ + int ret; + int finished; + + SSL_library_init(); + SSL_load_error_strings(); + + data->ssl_ctx = SSL_CTX_new(TLSv1_method()); + if(!data->ssl_ctx) return IKS_NOMEM; + + data->ssl = SSL_new(data->ssl_ctx); + if(!data->ssl) return IKS_NOMEM; + + if( SSL_set_fd(data->ssl, (int)data->sock) != 1 ) return IKS_NOMEM; + + /* Set both the read and write BIO's to non-blocking mode */ + BIO_set_nbio(SSL_get_rbio(data->ssl), 1); + BIO_set_nbio(SSL_get_wbio(data->ssl), 1); + + finished = 0; + + do + { + ret = SSL_connect(data->ssl); + + if( ret != 1 ) + { + if( wait_for_data(data, ret, 1) != IKS_OK ) + { + finished = 1; + SSL_free(data->ssl); + } + } + } while( ret != 1 && finished != 1 ); + + if( ret == 1 ) + { + data->flags &= (~SF_TRY_SECURE); + data->flags |= SF_SECURE; + + iks_send_header (data->prs, data->server); + } + + return ret == 1 ? IKS_OK : IKS_NET_TLSFAIL; } #endif @@ -295,6 +442,15 @@ tagHook (struct stream_data *data, char *name, char **atts, int type) return IKS_NET_TLSFAIL; } } +#elif HAVE_SSL + if (data->flags & SF_TRY_SECURE) { + if (strcmp (name, "proceed") == 0) { + err = handshake (data); + return err; + } else if (strcmp (name, "failure") == 0){ + return IKS_NET_TLSFAIL; + } + } #endif if (data->current) { x = iks_insert (data->current, name); @@ -351,6 +507,11 @@ deleteHook (struct stream_data *data) gnutls_deinit (data->sess); gnutls_certificate_free_credentials (data->cred); } +#elif HAVE_SSL + if (data->flags & SF_SECURE) { + if( SSL_shutdown(data->ssl) == 0 ) SSL_shutdown(data->ssl); + SSL_free(data->ssl); + } #endif if (data->trans) data->trans->close (data->sock); data->trans = NULL; @@ -507,6 +668,12 @@ iks_recv (iksparser *prs, int timeout) { struct stream_data *data = iks_user_data (prs); int len, ret; + +#ifdef HAVE_SSL + int err; + struct timeval tv; + fd_set fds; +#endif while (1) { #ifdef HAVE_GNUTLS @@ -514,6 +681,34 @@ iks_recv (iksparser *prs, int timeout) len = gnutls_record_recv (data->sess, data->buf, NET_IO_BUF_SIZE - 1); if (len == 0) len = -1; } else +#elif HAVE_SSL + if (data->flags & SF_SECURE) { + ret = sock_read_ready(data, timeout*1000); + + if (ret == -1) { + return IKS_NET_TLSFAIL; + } else if( ret == 0 ) { + return IKS_OK; + } else { + len = SSL_read(data->ssl, data->buf, NET_IO_BUF_SIZE - 1); + } + + if( len <= 0 ) + { + switch( err = SSL_get_error(data->ssl, len) ) + { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + return IKS_OK; + break; + default: + if(data->logHook) + data->logHook(data->user_data, ERR_error_string(err, NULL), strlen(ERR_error_string(err, NULL)), 1); + return IKS_NET_TLSFAIL; + break; + } + } + } else #endif { len = data->trans->recv (data->sock, data->buf, NET_IO_BUF_SIZE - 1, timeout); @@ -523,6 +718,7 @@ iks_recv (iksparser *prs, int timeout) data->buf[len] = '\0'; if (data->logHook) data->logHook (data->user_data, data->buf, len, 1); ret = iks_parse (prs, data->buf, len, 0); + if (ret != IKS_OK) return ret; if (!data->trans) { /* stream hook called iks_disconnect */ @@ -569,6 +765,10 @@ iks_send_raw (iksparser *prs, const char *xmlstr) if (data->flags & SF_SECURE) { if (gnutls_record_send (data->sess, xmlstr, strlen (xmlstr)) < 0) return IKS_NET_RWERR; } else +#elif HAVE_SSL + if (data->flags & SF_SECURE) { + if (SSL_write(data->ssl, xmlstr, strlen (xmlstr)) < 0) return IKS_NET_RWERR; + } else #endif { ret = data->trans->send (data->sock, xmlstr, strlen (xmlstr)); @@ -591,6 +791,8 @@ iks_has_tls (void) { #ifdef HAVE_GNUTLS return 1; +#elif HAVE_SSL + return 1; #else return 0; #endif @@ -602,6 +804,10 @@ iks_is_secure (iksparser *prs) #ifdef HAVE_GNUTLS struct stream_data *data = iks_user_data (prs); + return data->flags & SF_SECURE; +#elif HAVE_SSL + struct stream_data *data = iks_user_data (prs); + return data->flags & SF_SECURE; #else return 0; @@ -641,6 +847,14 @@ iks_start_tls (iksparser *prs) int ret; struct stream_data *data = iks_user_data (prs); + ret = iks_send_raw (prs, ""); + if (ret) return ret; + data->flags |= SF_TRY_SECURE; + return IKS_OK; +#elif HAVE_SSL + int ret; + struct stream_data *data = iks_user_data (prs); + ret = iks_send_raw (prs, ""); if (ret) return ret; data->flags |= SF_TRY_SECURE; diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c index 9ef6ef0958..f0b85e87f6 100644 --- a/libs/libdingaling/src/libdingaling.c +++ b/libs/libdingaling/src/libdingaling.c @@ -1498,59 +1498,11 @@ static ldl_queue_t ldl_flush_queue(ldl_handle_t *handle, int done) } -static void *APR_THREAD_FUNC queue_thread(apr_thread_t *thread, void *obj) -{ - ldl_handle_t *handle = (ldl_handle_t *) obj; - int timeout_ka = LDL_KEEPALIVE_TIMEOUT; - int count_ka = timeout_ka; - - ldl_set_flag_locked(handle, LDL_FLAG_QUEUE_RUNNING); - - while (ldl_test_flag(handle, LDL_FLAG_RUNNING) && !ldl_test_flag(handle, LDL_FLAG_QUEUE_STOP)) { - if (ldl_flush_queue(handle, 0) == LDL_QUEUE_SENT) { - count_ka = timeout_ka; - }; - - if (handle->loop_callback(handle) != LDL_STATUS_SUCCESS || !ldl_test_flag((&globals), LDL_FLAG_READY)) { - int fd; - - if ((fd = iks_fd(handle->parser)) > -1) { - shutdown(fd, 0x02); - } - ldl_set_flag_locked(handle, LDL_FLAG_BREAK); - break; - } - - if (count_ka-- <= 0) { - if( iks_send_raw(handle->parser, " ") == IKS_OK) { - count_ka = timeout_ka; - globals.logger(DL_LOG_DEBUG, "Sent keep alive signal\n"); - } - } - microsleep(100); - } - - ldl_clear_flag_locked(handle, LDL_FLAG_QUEUE_RUNNING); - ldl_clear_flag_locked(handle, LDL_FLAG_QUEUE_STOP); - - return NULL; -} - -static void launch_queue_thread(ldl_handle_t *handle) -{ - apr_thread_t *thread; - apr_threadattr_t *thd_attr;; - apr_threadattr_create(&thd_attr, handle->pool); - apr_threadattr_detach_set(thd_attr, 1); - - apr_threadattr_stacksize_set(thd_attr, 512 * 1024); - apr_thread_create(&thread, thd_attr, queue_thread, handle, handle->pool); - -} - - static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass) { + int timeout_ka = LDL_KEEPALIVE_TIMEOUT; + int count_ka = timeout_ka; + while (ldl_test_flag((&globals), LDL_FLAG_READY) && ldl_test_flag(handle, LDL_FLAG_RUNNING)) { int e; char tmp[512], *sl; @@ -1603,13 +1555,18 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass) } handle->counter = opt_timeout; - if (ldl_test_flag(handle, LDL_FLAG_TLS)) { - launch_queue_thread(handle); - } while (ldl_test_flag((&globals), LDL_FLAG_READY) && ldl_test_flag(handle, LDL_FLAG_RUNNING)) { e = iks_recv(handle->parser, 1); - if (!ldl_test_flag(handle, LDL_FLAG_TLS) && handle->loop_callback) { + + if (count_ka-- <= 0) { + if( iks_send_raw(handle->parser, " ") == IKS_OK) { + count_ka = timeout_ka; + globals.logger(DL_LOG_DEBUG, "Sent keep alive signal\n"); + } + } + + if (handle->loop_callback) { if (handle->loop_callback(handle) != LDL_STATUS_SUCCESS) { ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING); break; @@ -1630,7 +1587,7 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass) goto fail; } - if (!ldl_test_flag(handle, LDL_FLAG_TLS) && ldl_test_flag(handle, LDL_FLAG_RUNNING)) { + if (ldl_test_flag(handle, LDL_FLAG_RUNNING)) { ldl_flush_queue(handle, 0); } @@ -1648,11 +1605,12 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass) break; } } + + microsleep(100); } fail: - ldl_set_flag_locked(handle, LDL_FLAG_QUEUE_STOP); ldl_clear_flag_locked(handle, LDL_FLAG_CONNECTED); ldl_clear_flag_locked(handle, LDL_FLAG_AUTHORIZED); ldl_clear_flag_locked(handle, LDL_FLAG_BREAK); @@ -1662,23 +1620,12 @@ static void xmpp_connect(ldl_handle_t *handle, char *jabber_id, char *pass) shutdown(fd, 0x02); } - - - while(ldl_test_flag(handle, LDL_FLAG_QUEUE_RUNNING)) { - microsleep(100); - } - iks_disconnect(handle->parser); iks_parser_delete(handle->parser); } ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING); - if (!ldl_test_flag(handle, LDL_FLAG_TLS)) { - ldl_flush_queue(handle, 1); - } - while(ldl_test_flag(handle, LDL_FLAG_QUEUE_RUNNING)) { - microsleep(100); - } + ldl_flush_queue(handle, 1); ldl_set_flag_locked(handle, LDL_FLAG_STOPPED); @@ -2529,13 +2476,15 @@ int ldl_handle_authorized(ldl_handle_t *handle) void ldl_handle_stop(ldl_handle_t *handle) { ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING); +#if 0 if (ldl_test_flag(handle, LDL_FLAG_TLS)) { int fd; if ((fd = iks_fd(handle->parser)) > -1) { shutdown(fd, 0x02); } } - +#endif + while(!ldl_test_flag(handle, LDL_FLAG_STOPPED)) { microsleep(100); } diff --git a/libs/libdingaling/src/libdingaling.h b/libs/libdingaling/src/libdingaling.h index 504c12e820..28cc919e6b 100644 --- a/libs/libdingaling/src/libdingaling.h +++ b/libs/libdingaling/src/libdingaling.h @@ -121,10 +121,8 @@ typedef enum { LDL_FLAG_AUTHORIZED = (1 << 2), LDL_FLAG_READY = (1 << 3), LDL_FLAG_CONNECTED = (1 << 4), - LDL_FLAG_QUEUE_RUNNING = (1 << 5), - LDL_FLAG_STOPPED = (1 << 6), - LDL_FLAG_QUEUE_STOP = (1 << 7), - LDL_FLAG_BREAK = (1 << 8) + LDL_FLAG_STOPPED = (1 << 5), + LDL_FLAG_BREAK = (1 << 6) } ldl_flag_t; typedef enum { diff --git a/libs/win32/iksemel/iksemel.2008.vcproj b/libs/win32/iksemel/iksemel.2008.vcproj index 57c2dd9874..dc355838a1 100644 --- a/libs/win32/iksemel/iksemel.2008.vcproj +++ b/libs/win32/iksemel/iksemel.2008.vcproj @@ -41,6 +41,69 @@ + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - Disabled - ..\..\iksemel\include;.;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + ..\..\iksemel\include;.;..\..\openssl-1.0.0a\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;HAVE_SSL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -79,8 +79,8 @@ - ..\..\iksemel\include;.;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + ..\..\iksemel\include;.;..\..\openssl-1.0.0a\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;HAVE_SSL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) MultiThreadedDLL TurnOffAllWarnings @@ -91,8 +91,8 @@ Disabled - ..\..\iksemel\include;.;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + ..\..\iksemel\include;.;..\..\openssl-1.0.0a\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;HAVE_SSL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -104,8 +104,8 @@ X64 - ..\..\iksemel\include;.;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + ..\..\iksemel\include;.;..\..\openssl-1.0.0a\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;HAVE_SSL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) MultiThreadedDLL TurnOffAllWarnings diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.2010.vcxproj b/src/mod/endpoints/mod_dingaling/mod_dingaling.2010.vcxproj index 150ca184c4..67853235b2 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.2010.vcxproj +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.2010.vcxproj @@ -145,6 +145,12 @@ {e727e8f6-935d-46fe-8b0e-37834748a0e3} false + + {d331904d-a00a-4694-a5a3-fcff64ab5dbe} + + + {b4b62169-5ad4-4559-8707-3d933ac5db39} + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} false diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 1a7dd221ef..ee409ac38c 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -495,18 +495,24 @@ static switch_status_t chat_send(switch_event_t *message_event) mdl_profile_t *profile = NULL; const char *proto; const char *from; + const char *from_full; + const char *to_full; const char *to; const char *body; const char *hint; + const char *profile_name; proto = switch_event_get_header(message_event, "proto"); from = switch_event_get_header(message_event, "from"); + from_full = switch_event_get_header(message_event, "from_full"); + to_full = switch_event_get_header(message_event, "to_full"); to = switch_event_get_header(message_event, "to"); body = switch_event_get_body(message_event); hint = switch_event_get_header(message_event, "hint"); + profile_name = switch_event_get_header(message_event, "ldl_profile"); switch_assert(proto != NULL); - + if (from && (f_user = strdup(from))) { if ((f_host = strchr(f_user, '@'))) { *f_host++ = '\0'; @@ -516,12 +522,18 @@ static switch_status_t chat_send(switch_event_t *message_event) } } - if (to && (user = strdup(to))) { + if ((profile_name && (profile = switch_core_hash_find(globals.profile_hash, profile_name)))) { + from = from_full; + to = to_full; + + ldl_handle_send_msg(profile->handle, (char *) from, (char *) to, NULL, switch_str_nil(body)); + } else if (to && (user = strdup(to))) { if ((host = strchr(user, '@'))) { *host++ = '\0'; } - if (f_host && (profile = switch_core_hash_find(globals.profile_hash, f_host))) { + if (f_host && ((profile_name && (profile = switch_core_hash_find(globals.profile_hash, profile_name))) + || (profile = switch_core_hash_find(globals.profile_hash, f_host)))) { if (!strcmp(proto, MDL_CHAT_PROTO)) { from = hint; @@ -2931,6 +2943,8 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "subject", subject); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "text/plain"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hint", hint); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from_full", hint); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "ldl_profile", profile->name); if (msg) { switch_event_add_body(event, "%s", msg); @@ -2941,12 +2955,14 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi switch_safe_free(from_user); - if (strcasecmp(proto, MDL_CHAT_PROTO)) { /* yes no ! on purpose */ - switch_core_chat_send(proto, event); + if (!zstr(msg)) { + if (strcasecmp(proto, MDL_CHAT_PROTO)) { /* yes no ! on purpose */ + switch_core_chat_send(proto, event); + } + + switch_core_chat_send("GLOBAL", event); } - switch_core_chat_send("GLOBAL", event); - switch_event_destroy(&event); switch_safe_free(pproto);