43 Commits

Author SHA1 Message Date
James Booth
160a124619 OpenSSL: Debug certificate chain 2015-09-14 00:57:44 +01:00
James Booth
450bbca8e7 OpenSSL: Added debug logging to certificate verification 2015-09-13 22:44:12 +01:00
James Booth
20380157ba OpenSSL: debug name string on cert verify fail 2015-09-11 01:18:48 +01:00
James Booth
3e12f33cce OpenSSL: Use simpler cert callback 2015-09-11 00:46:49 +01:00
James Booth
f05529b09a Added open SSL dummy certificate check callback 2015-09-10 23:14:08 +01:00
James Booth
cc486b2ebf Continue open SSL connect loop on recoverable errors 2015-09-10 23:06:05 +01:00
James Booth
165d2487bb Change openssl connect err check for < 0 instead of == -1 2015-09-10 22:54:14 +01:00
James Booth
32591e3e77 Reformat tls_openssl.c 2015-09-10 22:51:15 +01:00
James Booth
cd92f69c76 Fixed Changelog 2015-08-18 22:07:06 +01:00
James Booth
73080e0660 Fixed indentation in Changelog 2015-08-18 22:00:43 +01:00
James Booth
7cdef1e319 Check for name element when reading mechanisms
Fixes an issue where the server sends whitespace between
elements, a segfault would occur when performing a strcmp
on the name.
2015-08-03 23:05:04 +01:00
James Booth
527bc0573a Fixed _log_open_tag to remove namespace prefix with libexpat 2015-03-28 17:37:11 +00:00
James Booth
59d2dd55d2 Added codelite project to .gitignore 2015-03-26 20:58:05 +00:00
James Booth
b1cbcffdc7 Bumped version, added to Changelog 2015-03-26 20:52:48 +00:00
James Booth
154b70ed2c Merge remote-tracking branch 'cwtitan/namespace' 2015-03-26 20:44:10 +00:00
Codewalker
e33a98e498 Streamline xmpp_stanza_to_text for the namespace patch by following XML
namespace scoping guidelines and not outputting the xmlns attribute in
contexts where it can be inferred from the parent element.
2015-01-23 11:11:23 -06:00
shooding
239d365ea1 fix Makefile.am to respect openssl_CFLAGS, which is useful if openssl is not installed in the default path, e.g. cross-compiling. 2015-01-14 18:06:35 +08:00
Dmitry Podgorny
57ed30b2bc autotools: fixed build with old versions of automake
Automake-1.11 and some newer versions fail if m4/ doesn't exist. This
behaviour was changed to warning in version 1.13.2.
2015-01-03 01:01:07 +02:00
Codewalker
86f913b001 Fix use of snprintf (which does not exist on all platforms) in auth.c
by replacing it with xmpp_snprintf in order to be consistent with the
rest of the code. Also fixes compile error on MSVC.
2015-01-02 20:21:59 +02:00
Codewalker
e2f1c1e94a Add XML namespace support. 2014-12-28 22:46:16 -06:00
Codewalker
f62d817c71 Fix error spam in event loop when no connections are open.
On Win32 at least, select() will immediately fail with an error if
there are no file descriptors to wait for (max == 0). In the simple case
of a single XMPP session and an event loop that runs only while the
connection is open, this isn't a problem, but doesn't work for more
complex scenarios.

Add some handling so that if xmpp_run_once is called and there are no
active connections, simply sleep for duration of the timeout and
return.
2014-12-24 12:08:05 -06:00
Codewalker
b753e6cf18 Fix a bug where select() could fail due to negative max socket fd.
Connection objects in the disconnected state should not have their
fd taken into account when determining the maximum socket fd number,
as they are not set in the bitmask with FD_SET, and their fd could
be anything, even a wildly large or small number.
2014-12-24 12:04:39 -06:00
Dmitry Podgorny
0fed8a55e4 examples: updated header in component.c 2014-12-15 14:47:47 +02:00
Dmitry Podgorny
d28520ba30 added examples/component to .gitignore 2014-12-15 14:42:50 +02:00
Milan Kubik
c52ba85846 XEP-0114: Added an example for component connection.
The example is based on basic.c program.
To run the example, a configured server is needed.
2014-12-15 14:42:50 +02:00
Dmitry Podgorny
3b906f6ceb XEP-0114: minor fixes to auth.c
- src/sha1.c is used instead of openssl;
 - xmpp_alloc/free should be used instead of malloc/free;
 - coding style fixes.
2014-12-15 14:42:50 +02:00
Milan Kubík
5d76e052ec XEP-0114: external component authentication
New API xmpp_connect_component() introduced.
2014-12-15 14:41:18 +02:00
Dariusz Dwornikowski
37a40dec23 Merge pull request #42 from tdi/master
Update headers not to mention LICENSE.txt but licenses directly Closes #31
2014-11-13 13:13:37 +01:00
Dmitry Podgorny
2093aac817 rpm: include shared library and pkg-config file 2014-10-31 04:13:49 +02:00
Kristofer White
29fa1bf27e Updates to rpm/libstrophe.spec 2014-10-31 04:11:13 +02:00
Dmitry Podgorny
f364ed184b autotools: fixed building of check_parser
By default libtool choose dynamic library for linking. Since non-public
API is hidden in libstrophe.so check_parser has been broken. As solution
libtool takes static libstophe.a now.
2014-10-30 23:17:16 +02:00
Dmitry Podgorny
40c9fe22b3 .gitignore: added files generated by make check 2014-10-30 23:16:40 +02:00
Dmitry Podgorny
c33c0a6998 hash: removed useless condition in hash_iter_next
Situation ((entry != NULL) && (i >= table->length)) can never happen.
2014-10-29 18:43:06 +02:00
Sergey Anufrienko
92e674e412 fix bug leading to losing of hash entries in hash_iter_next 2014-10-28 16:42:28 +03:00
Dmitry Podgorny
9f82aac8ce sha1: compile-time endianness check for some compilers
Newer gcc and clang provide macro __BYTE_ORDER__.
2014-10-25 16:37:21 +03:00
Dmitry Podgorny
a3f1b83f3a sha1: run-time check for endianness
WORDS_BIGENDIAN is never defined what breaks sha1 on big-endian
architectures. Instead, make run-time check.
2014-10-25 16:03:18 +03:00
Dariusz Dwornikowski
71f75b2e2e Closes #31 2014-10-23 08:44:52 +02:00
Dmitry Podgorny
b23104f920 ChangeLog: set future version to 0.8.7 2014-10-21 10:23:12 +03:00
Dmitry Podgorny
057f9068c6 autotools: removed duplication in configure.ac 2014-10-21 10:21:55 +03:00
Fabian Freyer
3231214344 Added --with-pkgconfigdir 2014-10-08 18:13:32 +02:00
Fabian Freyer
55efc601cb Refactored configure.ac, added pkg-config support 2014-10-08 18:13:31 +02:00
Fabian Freyer
dcbf3fb4d5 autotools: check for ssl.h if pkg-config failed
Some distros provides libssl without openssl.pc.
2014-09-30 16:02:43 +03:00
Fabian Freyer
e2acd98612 autotools: added AC_CONFIG_MACRO_DIR 2014-09-30 16:00:36 +03:00
53 changed files with 842 additions and 318 deletions

13
.gitignore vendored
View File

@@ -22,20 +22,24 @@ autom4te.cache
.sconsign*
src/*.o
examples/*.o
tests/*.o
tests/check_parser
*.a
*.pc
*.tar.gz
*.zip
docs/html
TAGS
tags
examples/basic
examples/active
examples/roster
examples/basic
examples/bot
examples/component
examples/roster
test_stamp
test-suite.log
tests/*.o
tests/*.log
tests/*.trs
tests/check_parser
tests/test_base64
tests/test_ctx
tests/test_hash
@@ -43,3 +47,4 @@ tests/test_jid
tests/test_sasl
tests/test_sock
m4/
libstrophe.project

View File

@@ -1,5 +1,10 @@
TBA
0.8.8
- XML namespace support
- XEP-0114 support
0.8.7
- SCRAM-SHA-1 authentication mechanism
- pkg-config support
0.8.5
- libtoolize to generate .so

View File

@@ -6,6 +6,7 @@ AM_CFLAGS = -g -Wall
PARSER_CFLAGS=@PARSER_CFLAGS@
PARSER_LIBS=@PARSER_LIBS@
SSL_CFLAGS = @openssl_CFLAGS@
SSL_LIBS = @openssl_LIBS@
STROPHE_FLAGS = -I$(top_srcdir)
@@ -14,7 +15,7 @@ STROPHE_LIBS = libstrophe.la
## Main build targets
lib_LTLIBRARIES = libstrophe.la
libstrophe_la_CFLAGS = $(STROPHE_FLAGS) $(PARSER_CFLAGS)
libstrophe_la_CFLAGS = $(SSL_CFLAGS) $(STROPHE_FLAGS) $(PARSER_CFLAGS)
libstrophe_la_LDFLAGS = $(SSL_LIBS) $(PARSER_LIBS)
# Export only public API
libstrophe_la_LDFLAGS += -export-symbols-regex '^xmpp_'
@@ -36,10 +37,12 @@ endif
include_HEADERS = strophe.h
noinst_HEADERS = strophepp.h
pkgconfig_DATA = libstrophe.pc
EXTRA_DIST = docs
## Examples
noinst_PROGRAMS = examples/active examples/roster examples/basic examples/bot
noinst_PROGRAMS = examples/active examples/roster examples/basic examples/bot examples/component
examples_active_SOURCES = examples/active.c
examples_active_CFLAGS = $(STROPHE_FLAGS)
examples_active_LDADD = $(STROPHE_LIBS)
@@ -51,7 +54,10 @@ examples_basic_CFLAGS = $(STROPHE_FLAGS)
examples_basic_LDADD = $(STROPHE_LIBS)
examples_bot_SOURCES = examples/bot.c
examples_bot_CFLAGS = $(STROPHE_FLAGS)
examples_bot_LDADD = $(STROPHE_LIBS)
examples_bot_LDADD = $(STROPHE_LIBS)
examples_component_SOURCES = examples/component.c
examples_component_CFLAGS = $(STROPHE_FLAGS)
examples_component_LDADD = $(STROPHE_LIBS)
## Tests
@@ -61,3 +67,4 @@ tests_check_parser_SOURCES = tests/check_parser.c tests/test.h
tests_check_parser_CFLAGS = @check_CFLAGS@ $(PARSER_CFLAGS) $(STROPHE_FLAGS) \
-I$(top_srcdir)/src
tests_check_parser_LDADD = @check_LIBS@ $(STROPHE_LIBS)
tests_check_parser_LDFLAGS = -static

View File

@@ -1,3 +1,5 @@
#!/bin/sh
# Some versions of aclocal fail if m4/ doesn't exist
mkdir -p m4
autoreconf -i

View File

@@ -1,4 +1,4 @@
AC_INIT([libstrophe], [0.8.7], [jack@metajack.im])
AC_INIT([libstrophe], [0.8.8], [jack@metajack.im])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign])
LT_INIT([dlopen])
@@ -12,8 +12,14 @@ AS_CASE([$host_os],
[freebsd*], [PLATFORM="freebsd"],
[PLATFORM="nix"])
PKG_CHECK_MODULES([openssl], [openssl], [],
[AC_CHECK_HEADER(openssl/ssl.h, [openssl_LIBS="-lssl -lcrypto"], [AC_MSG_ERROR([openssl not found; openssl required])])])
PKG_CHECK_MODULES([openssl], [openssl], [PC_REQUIRES+=(openssl)],
[AC_CHECK_HEADER([openssl/ssl.h],
[
openssl_LIBS="-lssl -lcrypto"
PC_LIBS+=($openssl_LIBS)
],
[AC_MSG_ERROR([openssl not found; openssl required])]
)])
PKG_CHECK_MODULES([check], [check >= 0.9.4], [], [AC_MSG_WARN([libcheck not found; unit tests will not be compilable])])
@@ -24,18 +30,35 @@ AC_ARG_WITH([libxml2],
if test "x$with_libxml2" != xno; then
PKG_CHECK_MODULES([libxml2], [libxml-2.0 >= 2.7],
[with_libxml2=yes], [dummy=1])
if test "x$with_libxml2" != xyes; then
old_CFLAGS=$CFLAGS
CFLAGS="-I${includedir}/libxml2"
AC_CHECK_HEADER([libxml/parser.h],
[with_libxml2=yes; libxml2_CFLAGS="-I${includedir}/libxml2"; libxml2_LIBS="-lxml2"],
[AC_MSG_ERROR([libxml2 not found.])])
CFLAGS=$old_CFLAGS
fi
[
with_libxml2=yes
PC_REQUIRES+=(libxml-2.0)
],
[
old_CFLAGS=$CFLAGS
CFLAGS="-I${includedir}/libxml2"
AC_CHECK_HEADER([libxml/parser.h],
[
with_libxml2=yes
libxml2_CFLAGS="-I${includedir}/libxml2"
libxml2_LIBS="-lxml2"
PC_LIBS+=($libxml2_LIBS)
PC_CFLAGS+=($libxml2_CFLAGS)
],
[AC_MSG_ERROR([libxml2 not found.])])
CFLAGS=$old_CFLAGS
])
else
PKG_CHECK_MODULES([expat], [expat >= 2.0.0], [],
[AC_CHECK_HEADER(expat.h, [expat_LIBS="-lexpat"], [AC_MSG_ERROR([expat not found; expat required.])])])
PKG_CHECK_MODULES([expat], [expat >= 2.0.0],
[PC_REQUIRES+=(expat)],
[AC_CHECK_HEADER([expat.h],
[
expat_LIBS="-lexpat"
PC_LIBS+=($expat_LIBS)
],
[AC_MSG_ERROR([expat not found; expat required.])]
)
])
fi
if test "x$with_libxml2" = xyes; then
@@ -56,16 +79,30 @@ AC_SEARCH_LIBS([socket], [socket])
if test "x$PLATFORM" != xfreebsd; then
AC_CHECK_LIB([resolv], [res_query], [],
[AC_CHECK_LIB([resolv], [__res_query], [],
[AC_MSG_ERROR([libresolv not found; libresolv required. ])])])
[AC_MSG_ERROR([libresolv not found; libresolv required.])])])
PC_LIBS+=(-lresolv)
else
AC_MSG_NOTICE([skipping libresolv checks for freebsd])
fi
AC_CHECK_HEADERS([arpa/nameser_compat.h])
m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR],
[AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir],
[install directory for libstrophe.pc pkg-config file])],
[],[with_pkgconfigdir='$(libdir)/pkgconfig'])
AC_SUBST([pkgconfigdir], [${with_pkgconfigdir}])])
AM_CONDITIONAL([PARSER_EXPAT], [test x$with_parser != xlibxml2])
AC_SUBST([PC_REQUIRES], [${PC_REQUIRES[[@]]}])
AC_SUBST([PC_CFLAGS], [${PC_CFLAGS[[@]]}])
AC_SUBST([PC_LIBS], [${PC_LIBS[[@]]}])
AC_SUBST(PARSER_NAME)
AC_SUBST(PARSER_CFLAGS)
AC_SUBST(PARSER_LIBS)
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([Makefile libstrophe.pc])
AC_OUTPUT

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/* This example demonstrates basic handler functions by printing out

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
#include <stdio.h>

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/* simple bot example

97
examples/component.c Normal file
View File

@@ -0,0 +1,97 @@
/* component.c
** libstrophe XMPP client library -- external component (XEP-0114) example
**
** Copyright (C) 2005-2009 Collecta, Inc.
**
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/* This example demonstrates simple connection to a server
** as an external component. See XEP-0114 for more details.
** This program requires correctly configured server to run.
*/
#include <stdio.h>
#include <stdlib.h>
#include <strophe.h>
/* define a handler for connection events */
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
const int error, xmpp_stream_error_t * const stream_error,
void * const userdata)
{
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
if (status == XMPP_CONN_CONNECT) {
fprintf(stderr, "DEBUG: connected\n");
xmpp_disconnect(conn);
}
else {
fprintf(stderr, "DEBUG: disconnected\n");
xmpp_stop(ctx);
}
}
int main(int argc, char **argv)
{
xmpp_ctx_t *ctx;
xmpp_conn_t *conn;
xmpp_log_t *log;
char *jid, *pass, *host, *port_err = NULL;
unsigned short port = 0;
/* take a jid and password on the command line */
if (argc < 4 || argc > 5) {
fprintf(stderr, "Usage: component <jid> <pass> <host> [<port>]\n\n");
return 1;
}
jid = argv[1];
pass = argv[2];
host = argv[3];
if (argc == 5) {
short tmp_port = (short) strtol(argv[4], &port_err, 10);
if (tmp_port < 0 || *port_err != '\0') {
fprintf(stderr, "Invalid value of <port> [%s].\n", argv[4]);
return 1;
}
port = (unsigned short) tmp_port;
}
/* init library */
xmpp_initialize();
/* create a context */
log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG); /* pass NULL instead to silence output */
ctx = xmpp_ctx_new(NULL, log);
/* create a connection */
conn = xmpp_conn_new(ctx);
/* setup authentication information */
xmpp_conn_set_jid(conn, jid);
xmpp_conn_set_pass(conn, pass);
/* initiate connection */
xmpp_connect_component(conn, host, port, conn_handler, ctx);
/* enter the event loop -
our connect handler will trigger an exit */
xmpp_run(ctx);
/* release our connection and context */
xmpp_conn_release(conn);
xmpp_ctx_free(ctx);
/* final shutdown of the library */
xmpp_shutdown();
return 0;
}

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/* This example demonstrates basic handler functions by printing out

14
libstrophe.pc.in Normal file
View File

@@ -0,0 +1,14 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libstrophe
Description: A simple, lightweight C library for writing XMPP clients
URL: http://strophe.im/libstrophe/
Version: @VERSION@
Requires:
Requires.private: @PC_REQUIRES@
Libs: -L${libdir} -lstrophe
Libs.private: @PC_LIBS@
Cflags: -I${includedir} @PC_CFLAGS@

View File

@@ -8,12 +8,24 @@ License: MIT/GPLv3
URL: http://strophe.im/libstrophe/
Source0: libstrophe_git.tar.gz
BuildRequires: automake
BuildRequires: libtool
BuildRequires: openssl-devel
BuildRequires: expat-devel
Requires: expat
Requires: expat
%description
XMPP library in C
%package devel
Summary: Headers and libraries for building apps that use libstrophe
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}
%description devel
This package contains headers and libraries required to build applications that
use the strophe XMPP library.
%prep
%setup -n libstrophe
./bootstrap.sh
@@ -25,8 +37,21 @@ make %{?_smp_mflags}
%install
make install DESTDIR=%{buildroot}
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr(-,root,root,-)
%{_libdir}/libstrophe.so*
%doc
%files devel
%defattr(-,root,root,-)
%{_libdir}/libstrophe.a
%{_libdir}/libstrophe.la
%{_libdir}/pkgconfig/libstrophe.pc
%{_includedir}/strophe.h
%doc
%changelog

View File

@@ -1,18 +1,15 @@
/* auth.c
** strophe XMPP client library -- auth functions and handlers
**
** Copyright (C) 2005-2009 Collecta, Inc.
** Copyright (C) 2005-2009 Collecta, Inc.
**
** This software is provided AS-IS with no warranty, either express or
** implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
/** @file
* Authentication function and handlers.
*/
@@ -24,6 +21,7 @@
#include "strophe.h"
#include "common.h"
#include "sasl.h"
#include "sha1.h"
#ifdef _MSC_VER
#define strcasecmp stricmp
@@ -55,9 +53,21 @@
*/
#define LEGACY_TIMEOUT 15000 /* 15 seconds */
#endif
#ifndef HANDSHAKE_TIMEOUT
/** @def HANDSHAKE_TIMEOUT
* Time to wait for component authentication to complete
*/
#define HANDSHAKE_TIMEOUT 15000 /* 15 seconds */
#endif
static void _auth(xmpp_conn_t * const conn);
static void _handle_open_sasl(xmpp_conn_t * const conn);
static int _handle_component_auth(xmpp_conn_t * const conn);
static int _handle_component_hs_response(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza,
void * const userdata);
static int _handle_missing_legacy(xmpp_conn_t * const conn,
void * const userdata);
static int _handle_legacy(xmpp_conn_t * const conn,
@@ -92,6 +102,8 @@ static int _handle_session(xmpp_conn_t * const conn,
void * const userdata);
static int _handle_missing_session(xmpp_conn_t * const conn,
void * const userdata);
static int _handle_missing_handshake(xmpp_conn_t * const conn,
void * const userdata);
/* stream:error handler */
static int _handle_error(xmpp_conn_t * const conn,
@@ -104,7 +116,7 @@ static int _handle_error(xmpp_conn_t * const conn,
/* free old stream error if it's still there */
if (conn->stream_error) {
xmpp_stanza_release(conn->stream_error->stanza);
if (conn->stream_error->text)
if (conn->stream_error->text)
xmpp_free(conn->ctx, conn->stream_error->text);
xmpp_free(conn->ctx, conn->stream_error);
}
@@ -225,9 +237,9 @@ static int _handle_features(xmpp_conn_t * const conn,
/* check for SASL */
child = xmpp_stanza_get_child_by_name(stanza, "mechanisms");
if (child && (strcmp(xmpp_stanza_get_ns(child), XMPP_NS_SASL) == 0)) {
for (mech = xmpp_stanza_get_children(child); mech;
for (mech = xmpp_stanza_get_children(child); mech;
mech = xmpp_stanza_get_next(mech)) {
if (strcmp(xmpp_stanza_get_name(mech), "mechanism") == 0) {
if (xmpp_stanza_get_name(mech) && strcmp(xmpp_stanza_get_name(mech), "mechanism") == 0) {
text = xmpp_stanza_get_text(mech);
if (strcasecmp(text, "PLAIN") == 0)
conn->sasl_support |= SASL_MASK_PLAIN;
@@ -244,7 +256,7 @@ static int _handle_features(xmpp_conn_t * const conn,
}
_auth(conn);
return 0;
}
@@ -269,7 +281,7 @@ static int _handle_proceedtls_default(xmpp_conn_t * const conn,
{
char *name;
name = xmpp_stanza_get_name(stanza);
xmpp_debug(conn->ctx, "xmpp",
xmpp_debug(conn->ctx, "xmpp",
"handle proceedtls called for %s", name);
if (strcmp(name, "proceed") == 0) {
@@ -283,7 +295,7 @@ static int _handle_proceedtls_default(xmpp_conn_t * const conn,
tls_free(conn->tls);
conn->tls = NULL;
conn->tls_failed = 1;
/* failed tls spoils the connection, so disconnect */
xmpp_disconnect(conn);
}
@@ -309,14 +321,14 @@ static int _handle_sasl_result(xmpp_conn_t * const conn,
/* the server should send a <success> or <failure> stanza */
if (strcmp(name, "failure") == 0) {
xmpp_debug(conn->ctx, "xmpp", "SASL %s auth failed",
xmpp_debug(conn->ctx, "xmpp", "SASL %s auth failed",
(char *)userdata);
/* fall back to next auth method */
_auth(conn);
} else if (strcmp(name, "success") == 0) {
/* SASL PLAIN auth successful, we need to restart the stream */
xmpp_debug(conn->ctx, "xmpp", "SASL %s auth successful",
xmpp_debug(conn->ctx, "xmpp", "SASL %s auth successful",
(char *)userdata);
/* reset parser */
@@ -361,10 +373,10 @@ static int _handle_digestmd5_challenge(xmpp_conn_t * const conn,
if (!auth) {
disconnect_mem_error(conn);
return 0;
}
}
xmpp_stanza_set_name(auth, "response");
xmpp_stanza_set_ns(auth, XMPP_NS_SASL);
authdata = xmpp_stanza_new(conn->ctx);
if (!authdata) {
disconnect_mem_error(conn);
@@ -377,7 +389,7 @@ static int _handle_digestmd5_challenge(xmpp_conn_t * const conn,
xmpp_stanza_add_child(auth, authdata);
xmpp_stanza_release(authdata);
handler_add(conn, _handle_digestmd5_rspauth,
handler_add(conn, _handle_digestmd5_rspauth,
XMPP_NS_SASL, NULL, NULL, NULL);
xmpp_send(conn, auth);
@@ -410,7 +422,7 @@ static int _handle_digestmd5_rspauth(xmpp_conn_t * const conn,
if (!auth) {
disconnect_mem_error(conn);
return 0;
}
}
xmpp_stanza_set_name(auth, "response");
xmpp_stanza_set_ns(auth, XMPP_NS_SASL);
xmpp_send(conn, auth);
@@ -543,7 +555,7 @@ static xmpp_stanza_t *_make_starttls(xmpp_conn_t * const conn)
xmpp_stanza_set_name(starttls, "starttls");
xmpp_stanza_set_ns(starttls, XMPP_NS_TLS);
}
return starttls;
}
@@ -559,14 +571,14 @@ static xmpp_stanza_t *_make_sasl_auth(xmpp_conn_t * const conn,
xmpp_stanza_set_ns(auth, XMPP_NS_SASL);
xmpp_stanza_set_attribute(auth, "mechanism", mechanism);
}
return auth;
}
/* authenticate the connection
* this may get called multiple times. if any auth method fails,
/* authenticate the connection
* this may get called multiple times. if any auth method fails,
* this will get called again until one auth method succeeds or every
* method fails
* method fails
*/
static void _auth(xmpp_conn_t * const conn)
{
@@ -607,7 +619,7 @@ static void _auth(xmpp_conn_t * const conn)
return;
}
handler_add(conn, _handle_proceedtls_default,
handler_add(conn, _handle_proceedtls_default,
XMPP_NS_TLS, NULL, NULL, NULL);
xmpp_send(conn, auth);
@@ -632,7 +644,7 @@ static void _auth(xmpp_conn_t * const conn)
/* SASL ANONYMOUS was tried, unset flag */
conn->sasl_support &= ~SASL_MASK_ANONYMOUS;
} else if (anonjid) {
xmpp_error(conn->ctx, "auth",
xmpp_error(conn->ctx, "auth",
"No node in JID, and SASL ANONYMOUS unsupported.");
xmpp_disconnect(conn);
} else if (conn->sasl_support & SASL_MASK_SCRAMSHA1) {
@@ -688,7 +700,7 @@ static void _auth(xmpp_conn_t * const conn)
}
handler_add(conn, _handle_digestmd5_challenge,
handler_add(conn, _handle_digestmd5_challenge,
XMPP_NS_SASL, NULL, NULL, NULL);
xmpp_send(conn, auth);
@@ -706,7 +718,7 @@ static void _auth(xmpp_conn_t * const conn)
if (!authdata) {
disconnect_mem_error(conn);
return;
}
}
authid = _get_authid(conn);
if (!authid) {
disconnect_mem_error(conn);
@@ -734,7 +746,7 @@ static void _auth(xmpp_conn_t * const conn)
conn->sasl_support &= ~SASL_MASK_PLAIN;
} else if (conn->type == XMPP_CLIENT) {
/* legacy client authentication */
iq = xmpp_stanza_new(conn->ctx);
if (!iq) {
disconnect_mem_error(conn);
@@ -820,7 +832,7 @@ static void _auth(xmpp_conn_t * const conn)
} else {
xmpp_stanza_release(authdata);
xmpp_stanza_release(iq);
xmpp_error(conn->ctx, "auth",
xmpp_error(conn->ctx, "auth",
"Cannot authenticate without resource");
xmpp_disconnect(conn);
return;
@@ -829,7 +841,7 @@ static void _auth(xmpp_conn_t * const conn)
xmpp_stanza_release(authdata);
handler_add_id(conn, _handle_legacy, "_xmpp_auth1", NULL);
handler_add_timed(conn, _handle_missing_legacy,
handler_add_timed(conn, _handle_missing_legacy,
LEGACY_TIMEOUT, NULL);
xmpp_send(conn, iq);
@@ -841,7 +853,7 @@ static void _auth(xmpp_conn_t * const conn)
/** Set up handlers at stream start.
* This function is called internally to Strophe for handling the opening
* of an XMPP stream. It's called by the parser when a stream is opened
* or reset, and adds the initial handlers for <stream:error/> and
* or reset, and adds the initial handlers for <stream:error/> and
* <stream:features/>. This function is not intended for use outside
* of Strophe.
*
@@ -854,11 +866,11 @@ void auth_handle_open(xmpp_conn_t * const conn)
/* setup handler for stream:error */
handler_add(conn, _handle_error,
NULL, "stream:error", NULL, NULL);
XMPP_NS_STREAMS, "error", NULL, NULL);
/* setup handlers for incoming <stream:features> */
handler_add(conn, _handle_features,
NULL, "stream:features", NULL, NULL);
XMPP_NS_STREAMS, "features", NULL, NULL);
handler_add_timed(conn, _handle_missing_features,
FEATURES_TIMEOUT, NULL);
}
@@ -870,7 +882,7 @@ static void _handle_open_sasl(xmpp_conn_t * const conn)
/* setup stream:features handlers */
handler_add(conn, _handle_features_sasl,
NULL, "stream:features", NULL, NULL);
XMPP_NS_STREAMS, "features", NULL, NULL);
handler_add_timed(conn, _handle_missing_features_sasl,
FEATURES_TIMEOUT, NULL);
}
@@ -903,7 +915,7 @@ static int _handle_features_sasl(xmpp_conn_t * const conn,
/* if bind is required, go ahead and start it */
if (conn->bind_required) {
/* bind resource */
/* setup response handlers */
handler_add_id(conn, _handle_bind, "_xmpp_bind1", NULL);
handler_add_timed(conn, _handle_missing_bind,
@@ -935,7 +947,7 @@ static int _handle_features_sasl(xmpp_conn_t * const conn,
resource = NULL;
}
/* if we have a resource to request, do it. otherwise the
/* if we have a resource to request, do it. otherwise the
server will assign us one */
if (resource) {
res = xmpp_stanza_new(conn->ctx);
@@ -986,7 +998,7 @@ static int _handle_missing_features_sasl(xmpp_conn_t * const conn,
xmpp_disconnect(conn);
return 0;
}
static int _handle_bind(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza,
void * const userdata)
@@ -1018,7 +1030,7 @@ static int _handle_bind(xmpp_conn_t * const conn,
if (conn->session_required) {
/* setup response handlers */
handler_add_id(conn, _handle_session, "_xmpp_session1", NULL);
handler_add_timed(conn, _handle_missing_session,
handler_add_timed(conn, _handle_missing_session,
SESSION_TIMEOUT, NULL);
/* send session request */
@@ -1049,9 +1061,9 @@ static int _handle_bind(xmpp_conn_t * const conn,
xmpp_stanza_release(iq);
} else {
conn->authenticated = 1;
/* call connection handler */
conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL,
conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL,
conn->userdata);
}
} else {
@@ -1088,7 +1100,7 @@ static int _handle_session(xmpp_conn_t * const conn,
xmpp_debug(conn->ctx, "xmpp", "Session establishment successful.");
conn->authenticated = 1;
/* call connection handler */
conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata);
} else {
@@ -1151,3 +1163,96 @@ static int _handle_missing_legacy(xmpp_conn_t * const conn,
return 0;
}
void auth_handle_component_open(xmpp_conn_t * const conn)
{
/* reset all timed handlers */
handler_reset_timed(conn, 0);
handler_add(conn, _handle_error, XMPP_NS_STREAMS, "error", NULL, NULL);
handler_add(conn, _handle_component_hs_response, NULL,
"handshake", NULL, NULL);
handler_add_timed(conn, _handle_missing_handshake, HANDSHAKE_TIMEOUT, NULL);
_handle_component_auth(conn);
}
/* Will compute SHA1 and authenticate the component to the server */
int _handle_component_auth(xmpp_conn_t * const conn)
{
uint8_t md_value[SHA1_DIGEST_SIZE];
SHA1_CTX mdctx;
char *digest;
size_t i;
/* Feed the session id and passphrase to the algorithm.
* We need to compute SHA1(session_id + passphrase)
*/
SHA1_Init(&mdctx);
SHA1_Update(&mdctx, (uint8_t*)conn->stream_id, strlen(conn->stream_id));
SHA1_Update(&mdctx, (uint8_t*)conn->pass, strlen(conn->pass));
SHA1_Final(&mdctx, md_value);
digest = xmpp_alloc(conn->ctx, 2*sizeof(md_value)+1);
if (digest) {
/* convert the digest into string representation */
for (i = 0; i < sizeof(md_value); i++)
xmpp_snprintf(digest+i*2, 3, "%02x", md_value[i]);
digest[2*sizeof(md_value)] = '\0';
xmpp_debug(conn->ctx, "auth", "Digest: %s, len: %d",
digest, strlen(digest));
/* Send the digest to the server */
xmpp_send_raw_string(conn, "<handshake xmlns='%s'>%s</handshake>",
XMPP_NS_COMPONENT, digest);
xmpp_debug(conn->ctx, "auth", "Sent component handshake to the server.");
xmpp_free(conn->ctx, digest);
} else {
xmpp_debug(conn->ctx, "auth", "Couldn't allocate memory for component "\
"handshake digest.");
xmpp_disconnect(conn);
return XMPP_EMEM;
}
return 0;
}
/* Check if the received stanza is <handshake/> and set auth to true
* and fire connection handler.
*/
int _handle_component_hs_response(xmpp_conn_t * const conn,
xmpp_stanza_t * const stanza,
void * const userdata)
{
char *name;
xmpp_timed_handler_delete(conn, _handle_missing_handshake);
name = xmpp_stanza_get_name(stanza);
if (strcmp(name, "handshake") != 0) {
char *msg;
size_t msg_size;
xmpp_stanza_to_text(stanza, &msg, &msg_size);
if (msg) {
xmpp_debug(conn->ctx, "auth", "Handshake failed: %s", msg);
xmpp_free(conn->ctx, msg);
}
xmpp_disconnect(conn);
return XMPP_EINT;
} else {
conn->authenticated = 1;
conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata);
}
/* We don't need this handler anymore, return 0 so it can be deleted
* from the list of handlers.
*/
return 0;
}
int _handle_missing_handshake(xmpp_conn_t * const conn, void * const userdata)
{
xmpp_error(conn->ctx, "xmpp", "Server did not reply to handshake request.");
xmpp_disconnect(conn);
return 0;
}

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express or
** implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
@@ -267,6 +264,7 @@ void disconnect_mem_error(xmpp_conn_t * const conn);
/* auth functions */
void auth_handle_open(xmpp_conn_t * const conn);
void auth_handle_component_open(xmpp_conn_t * const conn);
/* replacement snprintf and vsnprintf */
int xmpp_snprintf (char *str, size_t count, const char *fmt, ...);

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
@@ -442,6 +439,73 @@ int xmpp_connect_client(xmpp_conn_t * const conn,
return 0;
}
/** Initiate a component connection to server.
* This function returns immediately after starting the connection
* process to the XMPP server, and notifiations of connection state changes
* will be sent to the internal callback function that will set up handler
* for the component handshake as defined in XEP-0114.
* The domain and port to connect to must be provided in this case as the JID
* provided to the call serves as component identifier to the server and is
* not subject to DNS resolution.
*
* @param conn a Strophe connection object
* @param server a string with domain to use directly as the domain can't be
* extracted from the component name/JID. If this is not set, the call
* will fail.
* @param port an integer port number to use to connect to server expecting
* an external component. If this is 0, the port 5347 will be assumed.
* @param callback a xmpp_conn_handler callback function that will receive
* notifications of connection status
* @param userdata an opaque data pointer that will be passed to the callback
*
* @return 0 on success and -1 on an error
*
* @ingroup Connections
*/
int xmpp_connect_component(xmpp_conn_t * const conn, const char * const server,
unsigned short port, xmpp_conn_handler callback,
void * const userdata)
{
int connectport;
conn->type = XMPP_COMPONENT;
/* JID serves as an identificator here and will be used as "to" attribute
of the stream */
conn->domain = xmpp_strdup(conn->ctx, conn->jid);
/* The server domain, jid and password MUST be specified. */
if (!(server && conn->jid && conn->pass)) return -1;
connectport = port ? port : 5347;
xmpp_debug(conn->ctx, "xmpp", "Connecting via %s", server);
conn->sock = sock_connect(server, connectport);
xmpp_debug(conn->ctx, "xmpp", "sock_connect to %s:%d returned %d",
server, connectport, conn->sock);
if (conn->sock == -1) return -1;
/* XEP-0114 does not support TLS */
conn->tls_disabled = 1;
/* setup handler */
conn->conn_handler = callback;
conn->userdata = userdata;
conn_prepare_reset(conn, auth_handle_component_open);
/* FIXME: it could happen that the connect returns immediately as
* successful, though this is pretty unlikely. This would be a little
* hard to fix, since we'd have to detect and fire off the callback
* from within the event loop */
conn->state = XMPP_STATE_CONNECTING;
conn->timeout_stamp = time_stamp();
xmpp_debug(conn->ctx, "xmpp", "attempting to connect to %s", server);
return 0;
}
/** Cleanly disconnect the connection.
* This function is only called by the stream parser when </stream:stream>
* is received, and it not intended to be called by code outside of Strophe.
@@ -684,6 +748,7 @@ static void _log_open_tag(xmpp_conn_t *conn, char **attrs)
size_t pos;
int len;
int i;
char *attr;
if (!attrs) return;
@@ -692,10 +757,11 @@ static void _log_open_tag(xmpp_conn_t *conn, char **attrs)
if (len < 0) return;
pos += len;
for (i = 0; attrs[i]; i += 2) {
attr = parser_attr_name(conn->ctx, attrs[i]);
len = xmpp_snprintf(&buf[pos], 4096 - pos, " %s='%s'",
attrs[i], attrs[i+1]);
attr, attrs[i+1]);
xmpp_free(conn->ctx, attr);
if (len < 0) return;
pos += len;
}
@@ -725,7 +791,7 @@ static void _handle_stream_start(char *name, char **attrs,
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
char *id;
if (strcmp(name, "stream:stream") != 0) {
if (strcmp(name, "stream")) {
printf("name = %s\n", name);
xmpp_error(conn->ctx, "conn", "Server did not open valid stream.");
conn_disconnect(conn);
@@ -743,7 +809,7 @@ static void _handle_stream_start(char *name, char **attrs,
conn_disconnect(conn);
}
}
/* call stream open handler */
conn->open_handler(conn);
}

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
@@ -40,11 +37,14 @@
#ifndef _WIN32
#include <sys/select.h>
#include <errno.h>
#include <unistd.h>
#define _sleep(x) usleep(x*1000)
#else
#include <winsock2.h>
#define ETIMEDOUT WSAETIMEDOUT
#define ECONNRESET WSAECONNRESET
#define ECONNABORTED WSAECONNABORTED
#define _sleep(x) Sleep(x)
#endif
#include <strophe.h>
@@ -221,13 +221,20 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
tls_read_bytes += tls_pending(conn->tls);
}
if (conn->sock > max) max = conn->sock;
if (conn->state != XMPP_STATE_DISCONNECTED && conn->sock > max)
max = conn->sock;
connitem = connitem->next;
}
/* check for events */
ret = select(max + 1, &rfds, &wfds, NULL, &tv);
if (max > 0)
ret = select(max + 1, &rfds, &wfds, NULL, &tv);
else {
if (timeout > 0)
_sleep(timeout);
return;
}
/* select errored */
if (ret < 0) {

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
@@ -250,12 +247,13 @@ const char * hash_iter_next(hash_iterator_t *iter)
{
hash_t *table = iter->table;
hashentry_t *entry = iter->entry;
int i = iter->index + 1;
int i;
/* advance until we find the next entry */
if (entry != NULL) entry = entry->next;
if (entry == NULL) {
/* we're off the end of list, search for a new entry */
i = iter->index + 1;
while (i < iter->table->length) {
entry = table->entries[i];
if (entry != NULL) {
@@ -266,7 +264,7 @@ const char * hash_iter_next(hash_iterator_t *iter)
}
}
if ((entry == NULL) || (i >= table->length)) {
if (entry == NULL) {
/* no more keys! */
return NULL;
}

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
#include <stdlib.h>

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
#include "strophe.h"

View File

@@ -7,10 +7,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express or
** implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
@@ -37,6 +34,7 @@ parser_t *parser_new(xmpp_ctx_t *ctx,
parser_stanza_callback stanzacb,
void *userdata);
void parser_free(parser_t * const parser);
char* parser_attr_name(xmpp_ctx_t *ctx, char *nsname);
int parser_reset(parser_t *parser);
int parser_feed(parser_t *parser, char *chunk, int len);

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
@@ -26,6 +23,9 @@
#include "common.h"
#include "parser.h"
/* ASCII FF is invalid UTF-8 and should never be present in well-formed XML */
#define NAMESPACE_SEP ('\xFF')
struct _parser_t {
xmpp_ctx_t *ctx;
XML_Parser expat;
@@ -37,23 +37,71 @@ struct _parser_t {
xmpp_stanza_t *stanza;
};
/* return allocated string with the name from a delimited
* namespace/name string */
static char *_xml_name(xmpp_ctx_t *ctx, const char *nsname)
{
char *result = NULL;
const char *c;
int len;
c = strchr(nsname, NAMESPACE_SEP);
if (c == NULL) return xmpp_strdup(ctx, nsname);
c++;
len = strlen(c);
result = xmpp_alloc(ctx, len + 1);
if (result != NULL) {
memcpy(result, c, len);
result[len] = '\0';
}
return result;
}
/* return allocated string with the namespace from a delimited string */
static char *_xml_namespace(xmpp_ctx_t *ctx, const char *nsname)
{
char *result = NULL;
const char *c;
c = strchr(nsname, NAMESPACE_SEP);
if (c != NULL) {
result = xmpp_alloc(ctx, (c-nsname) + 1);
if (result != NULL) {
memcpy(result, nsname, (c-nsname));
result[c-nsname] = '\0';
}
}
return result;
}
static void _set_attributes(xmpp_stanza_t *stanza, const XML_Char **attrs)
{
char *attr;
int i;
if (!attrs) return;
for (i = 0; attrs[i]; i += 2) {
xmpp_stanza_set_attribute(stanza, attrs[i], attrs[i+1]);
/* namespaced attributes aren't used in xmpp, discard namespace */
attr = _xml_name(stanza->ctx, attrs[i]);
xmpp_stanza_set_attribute(stanza, attr, attrs[i+1]);
xmpp_free(stanza->ctx, attr);
}
}
static void _start_element(void *userdata,
const XML_Char *name,
const XML_Char *nsname,
const XML_Char **attrs)
{
parser_t *parser = (parser_t *)userdata;
xmpp_stanza_t *child;
char *ns, *name;
ns = _xml_namespace(parser->ctx, nsname);
name = _xml_name(parser->ctx, nsname);
if (parser->depth == 0) {
/* notify the owner */
@@ -74,6 +122,8 @@ static void _start_element(void *userdata,
}
xmpp_stanza_set_name(parser->stanza, name);
_set_attributes(parser->stanza, attrs);
if (ns)
xmpp_stanza_set_ns(parser->stanza, ns);
} else {
/* starting a child of parser->stanza */
child = xmpp_stanza_new(parser->ctx);
@@ -82,6 +132,8 @@ static void _start_element(void *userdata,
}
xmpp_stanza_set_name(child, name);
_set_attributes(child, attrs);
if (ns)
xmpp_stanza_set_ns(child, ns);
/* add child to parent */
xmpp_stanza_add_child(parser->stanza, child);
@@ -94,6 +146,9 @@ static void _start_element(void *userdata,
}
}
if (ns) xmpp_free(parser->ctx, ns);
if (name) xmpp_free(parser->ctx, name);
parser->depth++;
}
@@ -165,6 +220,11 @@ parser_t *parser_new(xmpp_ctx_t *ctx,
return parser;
}
char* parser_attr_name(xmpp_ctx_t *ctx, char *nsname)
{
return _xml_name(ctx, nsname);
}
/* free a parser */
void parser_free(parser_t *parser)
{
@@ -183,7 +243,7 @@ int parser_reset(parser_t *parser)
if (parser->stanza)
xmpp_stanza_release(parser->stanza);
parser->expat = XML_ParserCreate(NULL);
parser->expat = XML_ParserCreateNS(NULL, NAMESPACE_SEP);
if (!parser->expat) return 0;
parser->depth = 0;

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
@@ -39,28 +36,91 @@ struct _parser_t {
xmpp_stanza_t *stanza;
};
static void _set_attributes(xmpp_stanza_t *stanza, const xmlChar **attrs)
static void _set_attributes(xmpp_stanza_t *stanza, int nattrs,
const xmlChar **attrs)
{
int i;
int i, len;
char *value;
if (!attrs) return;
for (i = 0; attrs[i]; i += 2) {
xmpp_stanza_set_attribute(stanza, (const char *)attrs[i], (const char *)attrs[i+1]);
/* SAX2 uses array of localname/prefix/uri/value_begin/value_end */
for (i = 0; i < nattrs*5; i += 5) {
len = attrs[i+4] - attrs[i+3];
value = xmpp_alloc(stanza->ctx, len + 1);
if (value) {
memcpy(value, attrs[i+3], len);
value[len] = '\0';
xmpp_stanza_set_attribute(stanza, (const char *)attrs[i], value);
xmpp_free(stanza->ctx, value);
}
}
}
/* SAX2 gives us the attrs in an incredibly inconvenient array,
* convert it to what the start callback is expecting */
static char **_convert_attrs(parser_t *parser, int nattrs,
const xmlChar **attrs)
{
int c, i, o, len;
char *value;
char **ret;
if (!attrs) return NULL;
ret = xmpp_alloc(parser->ctx, (nattrs+1)*2*sizeof(char*));
if (!ret) return NULL;
memset(ret, 0, (nattrs+1)*2*sizeof(char*));
for (c = 0; c < nattrs; c++) {
i = c * 5;
o = c * 2;
len = attrs[i+4] - attrs[i+3];
value = xmpp_alloc(parser->ctx, len + 1);
if (value) {
memcpy(value, attrs[i+3], len);
value[len] = '\0';
ret[o] = xmpp_strdup(parser->ctx, (char*)attrs[i]);
ret[o+1] = value;
}
}
return ret;
}
static void _free_cbattrs(parser_t *parser, char **attrs)
{
int i;
if (!attrs)
return;
for (i = 0; attrs[i]; i += 2) {
if (attrs[i]) xmpp_free(parser->ctx, attrs[i]);
if (attrs[i+1]) xmpp_free(parser->ctx, attrs[i+1]);
}
xmpp_free(parser->ctx, attrs);
}
static void _start_element(void *userdata,
const xmlChar *name, const xmlChar **attrs)
const xmlChar *name, const xmlChar *prefix,
const xmlChar *uri, int nnamespaces,
const xmlChar **namespaces, int nattrs,
int ndefaulted, const xmlChar **attrs)
{
parser_t *parser = (parser_t *)userdata;
xmpp_stanza_t *child;
char **cbattrs;
if (parser->depth == 0) {
/* notify the owner */
if (parser->startcb)
parser->startcb((char *)name, (char **)attrs,
cbattrs = _convert_attrs(parser, nattrs, attrs);
parser->startcb((char *)name, cbattrs,
parser->userdata);
_free_cbattrs(parser, cbattrs);
} else {
/* build stanzas at depth 1 */
if (!parser->stanza && parser->depth != 1) {
@@ -74,7 +134,9 @@ static void _start_element(void *userdata,
/* FIXME: can't allocate, disconnect */
}
xmpp_stanza_set_name(parser->stanza, (char *)name);
_set_attributes(parser->stanza, attrs);
_set_attributes(parser->stanza, nattrs, attrs);
if (uri)
xmpp_stanza_set_ns(parser->stanza, (char *)uri);
} else {
/* starting a child of conn->stanza */
child = xmpp_stanza_new(parser->ctx);
@@ -82,7 +144,9 @@ static void _start_element(void *userdata,
/* FIXME: can't allocate, disconnect */
}
xmpp_stanza_set_name(child, (char *)name);
_set_attributes(child, attrs);
_set_attributes(child, nattrs, attrs);
if (uri)
xmpp_stanza_set_ns(child, (char *)uri);
/* add child to parent */
xmpp_stanza_add_child(parser->stanza, child);
@@ -98,7 +162,8 @@ static void _start_element(void *userdata,
parser->depth++;
}
static void _end_element(void *userdata, const xmlChar *name)
static void _end_element(void *userdata, const xmlChar *name,
const xmlChar *prefix, const xmlChar *uri)
{
parser_t *parser = (parser_t *)userdata;
@@ -156,8 +221,9 @@ parser_t *parser_new(xmpp_ctx_t *ctx,
parser->ctx = ctx;
parser->xmlctx = NULL;
memset(&parser->handlers, 0, sizeof(xmlSAXHandler));
parser->handlers.startElement = _start_element;
parser->handlers.endElement = _end_element;
parser->handlers.initialized = XML_SAX2_MAGIC;
parser->handlers.startElementNs = _start_element;
parser->handlers.endElementNs = _end_element;
parser->handlers.characters = _characters;
parser->startcb = startcb;
parser->endcb = endcb;
@@ -172,6 +238,11 @@ parser_t *parser_new(xmpp_ctx_t *ctx,
return parser;
}
char* parser_attr_name(xmpp_ctx_t *ctx, char *nsname)
{
return xmpp_strdup(ctx, nsname);
}
/* free a parser */
void parser_free(parser_t *parser)
{

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -9,10 +9,7 @@
* This software is provided AS-IS with no warranty, either express
* or implied.
*
* This software is distributed under license and may not be copied,
* modified or distributed except as expressly authorized under the
* terms of the license contained in the file LICENSE.txt in this
* distribution.
* This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
* This software is provided AS-IS with no warranty, either express
* or implied.
*
* This software is distributed under license and may not be copied,
* modified or distributed except as expressly authorized under the
* terms of the license contained in the file LICENSE.txt in this
* distribution.
* This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -90,19 +90,14 @@ A million repetitions of "a"
#include "sha1.h"
static uint32_t host_to_be(uint32_t i);
static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
/* FIXME: can we do this in an endian-proof way? */
#ifdef WORDS_BIGENDIAN
#define blk0(i) block->l[i]
#else
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#endif
#define blk0(i) (block->l[i] = host_to_be(block->l[i]))
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
@@ -127,6 +122,26 @@ void SHAPrintContext(SHA1_CTX *context, char *msg){
}
#endif /* VERBOSE */
static uint32_t host_to_be(uint32_t i)
{
#define le_to_be(i) ((rol((i),24) & 0xFF00FF00) | (rol((i),8) & 0x00FF00FF))
#if defined(__BIG_ENDIAN__) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
return i;
#elif defined(__LITTLE_ENDIAN__) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
return le_to_be(i);
#else /* fallback to run-time check */
static const union {
uint32_t u;
unsigned char c;
} check = {1};
return check.c ? le_to_be(i) : i;
#endif
}
/* Hash a single 512-bit block. This is the core of the algorithm. */
static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
{

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
@@ -320,6 +317,20 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
if (stanza->attributes && hash_num_keys(stanza->attributes) > 0) {
iter = hash_iter_new(stanza->attributes);
while ((key = hash_iter_next(iter))) {
if (!strcmp(key, "xmlns")) {
/* don't output namespace if parent stanza is the same */
if (stanza->parent &&
stanza->parent->attributes &&
hash_get(stanza->parent->attributes, key) &&
!strcmp((char*)hash_get(stanza->attributes, key),
(char*)hash_get(stanza->parent->attributes, key)))
continue;
/* or if this is the stream namespace */
if (!stanza->parent &&
!strcmp((char*)hash_get(stanza->attributes, key),
XMPP_NS_CLIENT))
continue;
}
tmp = _escape_xml(stanza->ctx,
(char *)hash_get(stanza->attributes, key));
if (tmp == NULL) return XMPP_EMEM;

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -1,15 +1,12 @@
/* tls_openssl.c
** strophe XMPP client library -- TLS abstraction openssl impl.
**
** Copyright (C) 2005-008 Collecta, Inc.
** Copyright (C) 2005-008 Collecta, Inc.
**
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
@@ -25,7 +22,6 @@
#endif
#include <openssl/ssl.h>
#include "common.h"
#include "tls.h"
#include "sock.h"
@@ -54,31 +50,136 @@ int tls_error(tls_t *tls)
return tls->lasterror;
}
int
convert_ASN1TIME(ASN1_TIME *ansi_time, char* buf, size_t len)
{
BIO *bio = BIO_new(BIO_s_mem());
int rc = ASN1_TIME_print(bio, ansi_time);
if (rc <= 0) {
BIO_free(bio);
return 0;
}
rc = BIO_gets(bio, buf, len);
if (rc <= 0) {
BIO_free(bio);
return 0;
}
BIO_free(bio);
return 1;
}
void
hex_encode(unsigned char* readbuf, void *writebuf, size_t len)
{
size_t i;
for(i=0; i < len; i++) {
char *l = (char*) (2*i + ((intptr_t) writebuf));
sprintf(l, "%02x", readbuf[i]);
}
}
static xmpp_ctx_t *xmppctx;
static void
print_certificate(X509* cert) {
char subj[1024+1];
char issuer[1024+1];
X509_NAME_oneline(X509_get_subject_name(cert), subj, 1024);
X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 1024);
xmpp_debug(xmppctx, "TLS", "SUBJECT : %s", subj);
xmpp_debug(xmppctx, "TLS", "ISSUER : %s", issuer);
}
static int
verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
X509 *cert = X509_STORE_CTX_get_current_cert(x509_ctx);
const STACK_OF(X509) *sk = X509_STORE_CTX_get1_chain(x509_ctx);
int slen = sk_num((const _STACK *)sk);
unsigned i;
X509 *certsk;
xmpp_debug(xmppctx, "TLS", "STACK");
for(i=0; i<slen; i++) {
certsk = (X509*) sk_value((const _STACK *)sk, i);
print_certificate(certsk);
}
xmpp_debug(xmppctx, "TLS", "ENDSTACK");
X509_NAME *subject = X509_get_subject_name(cert);
char *nameline = X509_NAME_oneline(subject, NULL, 0);
xmpp_debug(xmppctx, "TLS", "SUBJECT : %s", nameline);
OPENSSL_free(nameline);
X509_NAME *issuer = X509_get_issuer_name(cert);
nameline = X509_NAME_oneline(issuer, NULL, 0);
xmpp_debug(xmppctx, "TLS", "ISSUER : %s", nameline);
OPENSSL_free(nameline);
ASN1_TIME *not_before = X509_get_notBefore(cert);
char not_before_str[128];
int not_before_res = convert_ASN1TIME(not_before, not_before_str, 128);
if (not_before_res) {
xmpp_debug(xmppctx, "TLS", "NOT BEFORE : %s", not_before_str);
}
ASN1_TIME *not_after = X509_get_notAfter(cert);
char not_after_str[128];
int not_after_res = convert_ASN1TIME(not_after, not_after_str, 128);
if (not_after_res) {
xmpp_debug(xmppctx, "TLS", "NOT AFTER : %s", not_after_str);
}
char buf[20];
const EVP_MD *digest = EVP_sha1();
unsigned len;
int rc = X509_digest(cert, digest, (unsigned char*) buf, &len);
if (rc != 0 && len == 20) {
char strbuf[2*20+1];
hex_encode(buf, strbuf, 20);
xmpp_debug(xmppctx, "TLS", "FINGERPRINT : %s", strbuf);
}
if (preverify_ok) {
xmpp_debug(xmppctx, "TLS", "VERIFY SUCCESS");
return 1;
} else {
xmpp_debug(xmppctx, "TLS", "VERIFY FAILED");
int err = X509_STORE_CTX_get_error(x509_ctx);
const char *errstr = X509_verify_cert_error_string(err);
xmpp_debug(xmppctx, "TLS", "ERROR: %s", errstr);
return 1;
}
}
tls_t *tls_new(xmpp_ctx_t *ctx, sock_t sock)
{
xmppctx = ctx;
tls_t *tls = xmpp_alloc(ctx, sizeof(*tls));
if (tls) {
int ret;
memset(tls, 0, sizeof(*tls));
memset(tls, 0, sizeof(*tls));
tls->ctx = ctx;
tls->sock = sock;
tls->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
tls->ctx = ctx;
tls->sock = sock;
tls->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
SSL_CTX_set_client_cert_cb(tls->ssl_ctx, NULL);
SSL_CTX_set_mode (tls->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_set_verify (tls->ssl_ctx, SSL_VERIFY_NONE, NULL);
SSL_CTX_set_client_cert_cb(tls->ssl_ctx, NULL);
SSL_CTX_set_mode (tls->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_set_verify (tls->ssl_ctx, SSL_VERIFY_PEER, verify_callback);
tls->ssl = SSL_new(tls->ssl_ctx);
tls->ssl = SSL_new(tls->ssl_ctx);
ret = SSL_set_fd(tls->ssl, sock);
if (ret <= 0) {
tls->lasterror = SSL_get_error(tls->ssl, ret);
tls_error(tls);
tls_free(tls);
tls = NULL;
}
ret = SSL_set_fd(tls->ssl, sock);
if (ret <= 0) {
tls->lasterror = SSL_get_error(tls->ssl, ret);
tls_error(tls);
tls_free(tls);
tls = NULL;
}
}
return tls;
@@ -102,32 +203,35 @@ int tls_start(tls_t *tls)
int ret = -1;
/* Since we're non-blocking, loop the connect call until it
succeeds or fails */
while (ret == -1) {
ret = SSL_connect(tls->ssl);
succeeds or fails */
while (ret < 0) {
ret = SSL_connect(tls->ssl);
int err = SSL_get_error(tls->ssl, ret);
int recoverable = tls_is_recoverable(err);
/* wait for something to happen on the sock before looping back */
if (ret == -1) {
fd_set fds;
struct timeval tv;
// continue if recoverable
if (recoverable) {
fd_set fds;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 1000;
tv.tv_sec = 0;
tv.tv_usec = 1000;
FD_ZERO(&fds);
FD_SET(tls->sock, &fds);
select(tls->sock + 1, &fds, &fds, NULL, &tv);
}
FD_ZERO(&fds);
FD_SET(tls->sock, &fds);
select(tls->sock + 1, &fds, &fds, NULL, &tv);
} else {
ret = 1;
}
}
if (ret <= 0) {
tls->lasterror = SSL_get_error(tls->ssl, ret);
return 0;
tls->lasterror = SSL_get_error(tls->ssl, ret);
return 0;
}
return 1;
}
int tls_stop(tls_t *tls)
@@ -137,8 +241,8 @@ int tls_stop(tls_t *tls)
ret = SSL_shutdown(tls->ssl);
if (ret <= 0) {
tls->lasterror = SSL_get_error(tls->ssl, ret);
return 0;
tls->lasterror = SSL_get_error(tls->ssl, ret);
return 0;
}
return 1;
@@ -147,9 +251,9 @@ int tls_stop(tls_t *tls)
int tls_is_recoverable(int error)
{
return (error == SSL_ERROR_NONE || error == SSL_ERROR_WANT_READ
|| error == SSL_ERROR_WANT_WRITE
|| error == SSL_ERROR_WANT_CONNECT
|| error == SSL_ERROR_WANT_ACCEPT);
|| error == SSL_ERROR_WANT_WRITE
|| error == SSL_ERROR_WANT_CONNECT
|| error == SSL_ERROR_WANT_ACCEPT);
}
int tls_pending(tls_t *tls)
@@ -162,7 +266,7 @@ int tls_read(tls_t *tls, void * const buff, const size_t len)
int ret = SSL_read(tls->ssl, buff, len);
if (ret <= 0) {
tls->lasterror = SSL_get_error(tls->ssl, ret);
tls->lasterror = SSL_get_error(tls->ssl, ret);
}
return ret;
@@ -173,7 +277,7 @@ int tls_write(tls_t *tls, const void * const buff, const size_t len)
int ret = SSL_write(tls->ssl, buff, len);
if (ret <= 0) {
tls->lasterror = SSL_get_error(tls->ssl, ret);
tls->lasterror = SSL_get_error(tls->ssl, ret);
}
return ret;

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express or
** implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This software is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file
@@ -225,9 +222,10 @@ int xmpp_connect_client(xmpp_conn_t * const conn,
xmpp_conn_handler callback,
void * const userdata);
/*
int xmpp_connect_component(conn, name)
*/
int xmpp_connect_component(xmpp_conn_t * const conn, const char * const server,
unsigned short port, xmpp_conn_handler callback,
void * const userdata);
void xmpp_disconnect(xmpp_conn_t * const conn);
void xmpp_send(xmpp_conn_t * const conn,

View File

@@ -5,11 +5,8 @@
**
** This software is provided AS-IS with no warranty, either express or
** implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
**
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
/** @file

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express or
** implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
#include <stdlib.h>
@@ -37,14 +34,14 @@ END_TEST
int cbtest_got_start = 0;
void cbtest_handle_start(char *name, char **attrs, void *userdata)
{
if (strcmp(name, "stream:stream") == 0)
if (strcmp(name, "stream") == 0)
cbtest_got_start = 1;
}
int cbtest_got_end = 0;
void cbtest_handle_end(char *name, void *userdata)
{
if (strcmp(name, "stream:stream") == 0)
if (strcmp(name, "stream") == 0)
cbtest_got_end = 1;
}
@@ -67,9 +64,9 @@ START_TEST(callbacks)
cbtest_handle_end,
cbtest_handle_stanza, NULL);
ret = parser_feed(parser, "<stream:stream>", 15);
ret = parser_feed(parser, "<stream>", 8);
ret = parser_feed(parser, "<message/>", 10);
parser_feed(parser, "</stream:stream>", 16);
parser_feed(parser, "</stream>", 9);
fail_unless(cbtest_got_start == 1);
fail_unless(cbtest_got_end == 1);

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
#include <stdio.h>

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
#include <stdio.h>

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
#include <stdlib.h>

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
#include <stdio.h>

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
#include <stdio.h>

View File

@@ -6,10 +6,7 @@
** This software is provided AS-IS with no warranty, either express
** or implied.
**
** This software is distributed under license and may not be copied,
** modified or distributed except as expressly authorized under the
** terms of the license contained in the file LICENSE.txt in this
** distribution.
** This program is dual licensed under the MIT and GPLv3 licenses.
*/
#include <stdio.h>