Compare commits
24 Commits
0.10.1
...
tls-secure
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06cb1459f1 | ||
|
|
82f372fa49 | ||
|
|
9ddc881102 | ||
|
|
f6ef50d134 | ||
|
|
bd87653c76 | ||
|
|
2f491e0250 | ||
|
|
2509ed8424 | ||
|
|
f3e3e64a17 | ||
|
|
d7a28f97a6 | ||
|
|
2199d8d088 | ||
|
|
d1ce4b35ae | ||
|
|
e77cd53215 | ||
|
|
588aea4f54 | ||
|
|
ee5f9fb77b | ||
|
|
4790a61437 | ||
|
|
25d3a2d459 | ||
|
|
27be6acaeb | ||
|
|
9a0e070c24 | ||
|
|
e490011b68 | ||
|
|
3b4b664c28 | ||
|
|
18c95fa7bd | ||
|
|
cf2f7147d9 | ||
|
|
ecf6457cdb | ||
|
|
db8a511f68 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -61,6 +61,7 @@ tests/test_snprintf
|
||||
tests/test_sock
|
||||
tests/test_stanza
|
||||
tests/test_string
|
||||
tests/test_xmppaddr
|
||||
m4/
|
||||
libstrophe.project
|
||||
libs/
|
||||
|
||||
18
.travis.yml
18
.travis.yml
@@ -1,26 +1,26 @@
|
||||
language: c
|
||||
dist: focal
|
||||
install:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get -y install libtool pkg-config libexpat1-dev libxml2-dev libssl-dev libc-ares-dev dos2unix
|
||||
- sudo apt-get -y install libtool pkg-config libexpat1-dev libxml2-dev libssl-dev libgnutls28-dev libc-ares-dev dos2unix
|
||||
stages:
|
||||
- style
|
||||
- test
|
||||
before_script:
|
||||
- ./travis/before_script.sh
|
||||
env:
|
||||
- CONFIGURE_OPT="--without-libxml2"
|
||||
- CONFIGURE_OPT="--with-libxml2"
|
||||
- CONFIGURE_OPT="--with-gnutls"
|
||||
- CONFIGURE_OPT="--disable-tls"
|
||||
- CONFIGURE_OPT="--enable-cares"
|
||||
- CONFIGURE_OPT="PKG_CONFIG_PATH=${HOME}/libressl/lib/pkgconfig" LIBRESSL=yes LIBRESSL_COMMIT="v3.1.4"
|
||||
- CONFIGURE_OPT="PKG_CONFIG_PATH=${HOME}/libressl/lib/pkgconfig" LIBRESSL=yes LIBRESSL_COMMIT="v2.1.7"
|
||||
script: ./bootstrap.sh && ./configure ${CONFIGURE_OPT} CFLAGS="-Werror" && make && make check
|
||||
before_script: ./travis/before_script.sh
|
||||
script: ./bootstrap.sh && ./configure ${CONFIGURE_OPT} CFLAGS="-Werror -g3" && make && make check
|
||||
jobs:
|
||||
include:
|
||||
- stage: style
|
||||
name: "Check code style"
|
||||
name: "Check coding style"
|
||||
env: CONFIGURE_OPT=""
|
||||
script: ./bootstrap.sh && ./configure && make format && git diff --exit-code
|
||||
env:
|
||||
- CONFIGURE_OPT=""
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- stage: style
|
||||
|
||||
12
ChangeLog
12
ChangeLog
@@ -1,3 +1,15 @@
|
||||
0.11.0
|
||||
- SASL EXTERNAL support (XEP-0178)
|
||||
- Client certificate can be provided for TLS negotiation. If the
|
||||
certificate contains a single xmppAddr and JID is not provided with
|
||||
xmpp_conn_set_jid(), the xmppAddr is chosen as JID
|
||||
- <stream> element contains "from" attribute over TLS connections now
|
||||
- GnuTLS can be selected optionally with configure script
|
||||
- New API:
|
||||
- xmpp_conn_set_client_cert()
|
||||
- xmpp_conn_cert_xmppaddr_num()
|
||||
- xmpp_conn_cert_xmppaddr()
|
||||
|
||||
0.10.1
|
||||
- Fixed compilation error when LibreSSL is used
|
||||
- Fixed crash when NULL is provided as password
|
||||
|
||||
2
Doxyfile
2
Doxyfile
@@ -1047,7 +1047,7 @@ HTML_HEADER =
|
||||
# that doxygen normally uses.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_FOOTER = docs/footer.html
|
||||
HTML_FOOTER =
|
||||
|
||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
|
||||
# sheet that is used by each HTML page. It can be used to fine-tune the look of
|
||||
|
||||
26
Makefile.am
26
Makefile.am
@@ -5,8 +5,13 @@ ACLOCAL_AMFLAGS = -I m4
|
||||
PARSER_CFLAGS=@PARSER_CFLAGS@
|
||||
PARSER_LIBS=@PARSER_LIBS@
|
||||
|
||||
if TLS_WITH_GNUTLS
|
||||
SSL_CFLAGS = @gnutls_CFLAGS@
|
||||
SSL_LIBS = @gnutls_LIBS@
|
||||
else
|
||||
SSL_CFLAGS = @openssl_CFLAGS@
|
||||
SSL_LIBS = @openssl_LIBS@
|
||||
endif
|
||||
|
||||
RESOLV_CFLAGS = @RESOLV_CFLAGS@
|
||||
RESOLV_LIBS = @RESOLV_LIBS@
|
||||
@@ -67,8 +72,12 @@ libstrophe_la_SOURCES += \
|
||||
if DISABLE_TLS
|
||||
libstrophe_la_SOURCES += src/tls_dummy.c
|
||||
else
|
||||
if TLS_WITH_GNUTLS
|
||||
libstrophe_la_SOURCES += src/tls_gnutls.c
|
||||
else
|
||||
libstrophe_la_SOURCES += src/tls_openssl.c
|
||||
endif
|
||||
endif
|
||||
|
||||
if PARSER_EXPAT
|
||||
libstrophe_la_SOURCES += src/parser_expat.c
|
||||
@@ -92,10 +101,16 @@ EXTRA_DIST = \
|
||||
examples/README.md \
|
||||
jni/Android.mk \
|
||||
jni/Application.mk \
|
||||
src/tls_gnutls.c \
|
||||
src/tls_schannel.c \
|
||||
src/tls_securetransport.c \
|
||||
tests/res_query_dump.c
|
||||
|
||||
if TLS_WITH_GNUTLS
|
||||
EXTRA_DIST += src/tls_openssl.c
|
||||
else
|
||||
EXTRA_DIST += src/tls_gnutls.c
|
||||
endif
|
||||
|
||||
## Examples
|
||||
noinst_PROGRAMS = \
|
||||
examples/active \
|
||||
@@ -151,6 +166,10 @@ TESTS = \
|
||||
tests/test_stanza \
|
||||
tests/test_resolver
|
||||
|
||||
if !DISABLE_TLS
|
||||
TESTS += tests/test_xmppaddr
|
||||
endif
|
||||
|
||||
check_PROGRAMS = $(TESTS)
|
||||
|
||||
tests_check_parser_SOURCES = tests/check_parser.c tests/test.h
|
||||
@@ -216,6 +235,11 @@ tests_test_stanza_CFLAGS = $(STROPHE_FLAGS)
|
||||
tests_test_stanza_LDADD = $(STROPHE_LIBS)
|
||||
tests_test_stanza_LDFLAGS = -static
|
||||
|
||||
tests_test_xmppaddr_SOURCES = tests/test_xmppaddr.c
|
||||
tests_test_xmppaddr_CFLAGS = $(STROPHE_FLAGS) -I$(top_srcdir)/src
|
||||
tests_test_xmppaddr_LDADD = $(STROPHE_LIBS)
|
||||
tests_test_xmppaddr_LDFLAGS = -static
|
||||
|
||||
format:
|
||||
@echo " * run clang-format on all sources"
|
||||
@dos2unix -q src/*.[ch] *.h tests/*.[ch] examples/*.c
|
||||
|
||||
15
configure.ac
15
configure.ac
@@ -26,6 +26,8 @@ AS_CASE([$PLATFORM],
|
||||
|
||||
AC_ARG_WITH([libxml2],
|
||||
[AS_HELP_STRING([--with-libxml2], [use libxml2 for XML parsing, expat is the default])])
|
||||
AC_ARG_WITH([gnutls],
|
||||
[AS_HELP_STRING([--with-gnutls], [use GnuTLS for TLS support, OpenSSL is the default])])
|
||||
AC_ARG_ENABLE([tls],
|
||||
[AS_HELP_STRING([--disable-tls], [disable TLS support])])
|
||||
AC_ARG_ENABLE([cares],
|
||||
@@ -35,7 +37,17 @@ AC_SEARCH_LIBS([socket], [network socket])
|
||||
AC_CHECK_FUNCS([snprintf vsnprintf])
|
||||
AC_CHECK_DECLS([va_copy], [], [], [#include <stdarg.h>])
|
||||
|
||||
if test "x$enable_tls" != xno; then
|
||||
if test "x$enable_tls" != xno -a "x$with_gnutls" == xyes; then
|
||||
PKG_CHECK_MODULES([gnutls], [gnutls],
|
||||
[PC_REQUIRES="gnutls ${PC_REQUIRES}"],
|
||||
[AC_CHECK_HEADER([gnutls/gnutls.h],
|
||||
[
|
||||
gnutls_LIBS="-lgnutls"
|
||||
PC_LIBS="${gnutls_LIBS} ${PC_LIBS}"
|
||||
],
|
||||
[AC_MSG_ERROR([gnutls not found; gnutls required])]
|
||||
)])
|
||||
elif test "x$enable_tls" != xno; then
|
||||
PKG_CHECK_MODULES([openssl], [openssl],
|
||||
[PC_REQUIRES="openssl ${PC_REQUIRES}"],
|
||||
[AC_CHECK_HEADER([openssl/ssl.h],
|
||||
@@ -145,6 +157,7 @@ m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR],
|
||||
|
||||
AM_CONDITIONAL([PARSER_EXPAT], [test x$with_parser != xlibxml2])
|
||||
AM_CONDITIONAL([DISABLE_TLS], [test x$enable_tls = xno])
|
||||
AM_CONDITIONAL([TLS_WITH_GNUTLS], [test x$with_gnutls = xyes])
|
||||
|
||||
AC_SUBST([PC_REQUIRES], [${PC_REQUIRES}])
|
||||
AC_SUBST([PC_CFLAGS], [${PC_CFLAGS}])
|
||||
|
||||
0
docs/.keep
Normal file
0
docs/.keep
Normal file
@@ -1,2 +0,0 @@
|
||||
</body>
|
||||
</html>
|
||||
@@ -19,9 +19,7 @@
|
||||
|
||||
#include <strophe.h>
|
||||
|
||||
int handle_reply(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
int handle_reply(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
xmpp_stanza_t *query, *item;
|
||||
const char *type;
|
||||
@@ -46,11 +44,11 @@ int handle_reply(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
void conn_handler(xmpp_conn_t *conn,
|
||||
xmpp_conn_event_t status,
|
||||
int error,
|
||||
xmpp_stream_error_t *stream_error,
|
||||
void *userdata)
|
||||
{
|
||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||
xmpp_stanza_t *iq, *query;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <strophe.h>
|
||||
@@ -19,11 +20,11 @@
|
||||
#define KA_INTERVAL 1
|
||||
|
||||
/* 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)
|
||||
void conn_handler(xmpp_conn_t *conn,
|
||||
xmpp_conn_event_t status,
|
||||
int error,
|
||||
xmpp_stream_error_t *stream_error,
|
||||
void *userdata)
|
||||
{
|
||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||
int secured;
|
||||
@@ -43,19 +44,43 @@ void conn_handler(xmpp_conn_t *const conn,
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(int exit_code)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: basic [options] [<host> [<port>]]\n\n"
|
||||
"Options:\n"
|
||||
" --jid <jid> The JID to use to authenticate.\n"
|
||||
" --pass <pass> The password of the JID.\n"
|
||||
" --tls-cert <cert> Path to client certificate.\n"
|
||||
" --tls-key <key> Path to private key.\n\n"
|
||||
" --disable-tls Disable TLS.\n"
|
||||
" --mandatory-tls Deny plaintext connection.\n"
|
||||
" --trust-tls Trust TLS certificate.\n"
|
||||
" --legacy-ssl Use old style SSL.\n"
|
||||
" --legacy-auth Allow legacy authentication.\n"
|
||||
" --tcp-keepalive Configure TCP keepalive.\n\n"
|
||||
"Note: --disable-tls conflicts with --mandatory-tls or "
|
||||
"--legacy-ssl\n");
|
||||
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
xmpp_ctx_t *ctx;
|
||||
xmpp_conn_t *conn;
|
||||
xmpp_log_t *log;
|
||||
char *jid, *pass, *host = NULL;
|
||||
char *jid = NULL, *password = NULL, *cert = NULL, *key = NULL, *host = NULL;
|
||||
long flags = 0;
|
||||
int tcp_keepalive = 0;
|
||||
int i;
|
||||
unsigned long port = 0;
|
||||
|
||||
/* take a jid and password on the command line */
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "--disable-tls") == 0)
|
||||
if (strcmp(argv[i], "--help") == 0)
|
||||
usage(0);
|
||||
else if (strcmp(argv[i], "--disable-tls") == 0)
|
||||
flags |= XMPP_CONN_FLAG_DISABLE_TLS;
|
||||
else if (strcmp(argv[i], "--mandatory-tls") == 0)
|
||||
flags |= XMPP_CONN_FLAG_MANDATORY_TLS;
|
||||
@@ -67,27 +92,25 @@ int main(int argc, char **argv)
|
||||
flags |= XMPP_CONN_FLAG_LEGACY_AUTH;
|
||||
else if (strcmp(argv[i], "--tcp-keepalive") == 0)
|
||||
tcp_keepalive = 1;
|
||||
else if ((strcmp(argv[i], "--jid") == 0) && (++i < argc))
|
||||
jid = argv[i];
|
||||
else if ((strcmp(argv[i], "--pass") == 0) && (++i < argc))
|
||||
password = argv[i];
|
||||
else if ((strcmp(argv[i], "--tls-cert") == 0) && (++i < argc))
|
||||
cert = argv[i];
|
||||
else if ((strcmp(argv[i], "--tls-key") == 0) && (++i < argc))
|
||||
key = argv[i];
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ((argc - i) < 2 || (argc - i) > 3) {
|
||||
fprintf(stderr, "Usage: basic [options] <jid> <pass> [<host>]\n\n"
|
||||
"Options:\n"
|
||||
" --disable-tls Disable TLS.\n"
|
||||
" --mandatory-tls Deny plaintext connection.\n"
|
||||
" --trust-tls Trust TLS certificate.\n"
|
||||
" --legacy-ssl Use old style SSL.\n"
|
||||
" --legacy-auth Allow legacy authentication.\n"
|
||||
" --tcp-keepalive Configure TCP keepalive.\n\n"
|
||||
"Note: --disable-tls conflicts with --mandatory-tls or "
|
||||
"--legacy-ssl\n");
|
||||
return 1;
|
||||
if ((!jid && (!cert || !key)) || (argc - i) > 2) {
|
||||
usage(1);
|
||||
}
|
||||
|
||||
jid = argv[i];
|
||||
pass = argv[i + 1];
|
||||
if (i + 2 < argc)
|
||||
host = argv[i + 2];
|
||||
if (i < argc)
|
||||
host = argv[i];
|
||||
if (i + 1 < argc)
|
||||
port = strtoul(argv[i + 1], NULL, 0);
|
||||
|
||||
/*
|
||||
* Note, this example doesn't handle errors. Applications should check
|
||||
@@ -112,15 +135,21 @@ int main(int argc, char **argv)
|
||||
xmpp_conn_set_keepalive(conn, KA_TIMEOUT, KA_INTERVAL);
|
||||
|
||||
/* setup authentication information */
|
||||
xmpp_conn_set_jid(conn, jid);
|
||||
xmpp_conn_set_pass(conn, pass);
|
||||
if (cert && key) {
|
||||
xmpp_conn_set_client_cert(conn, cert, key);
|
||||
}
|
||||
if (jid)
|
||||
xmpp_conn_set_jid(conn, jid);
|
||||
if (password)
|
||||
xmpp_conn_set_pass(conn, password);
|
||||
|
||||
/* initiate connection */
|
||||
xmpp_connect_client(conn, host, 0, conn_handler, ctx);
|
||||
if (xmpp_connect_client(conn, host, port, conn_handler, ctx) == XMPP_EOK) {
|
||||
|
||||
/* enter the event loop -
|
||||
our connect handler will trigger an exit */
|
||||
xmpp_run(ctx);
|
||||
/* enter the event loop -
|
||||
our connect handler will trigger an exit */
|
||||
xmpp_run(ctx);
|
||||
}
|
||||
|
||||
/* release our connection and context */
|
||||
xmpp_conn_release(conn);
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
|
||||
#include <strophe.h>
|
||||
|
||||
int version_handler(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
int version_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
xmpp_stanza_t *reply, *query, *name, *version, *text;
|
||||
const char *ns;
|
||||
@@ -70,9 +68,7 @@ int version_handler(xmpp_conn_t *const conn,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int message_handler(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
int message_handler(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||
xmpp_stanza_t *body, *reply;
|
||||
@@ -118,11 +114,11 @@ int message_handler(xmpp_conn_t *const conn,
|
||||
}
|
||||
|
||||
/* 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)
|
||||
void conn_handler(xmpp_conn_t *conn,
|
||||
xmpp_conn_event_t status,
|
||||
int error,
|
||||
xmpp_stream_error_t *stream_error,
|
||||
void *userdata)
|
||||
{
|
||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
#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)
|
||||
void conn_handler(xmpp_conn_t *conn,
|
||||
xmpp_conn_event_t status,
|
||||
int error,
|
||||
xmpp_stream_error_t *stream_error,
|
||||
void *userdata)
|
||||
{
|
||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||
|
||||
|
||||
@@ -102,9 +102,7 @@ iq_reg_send_form(xmpp_reg_t *reg, xmpp_conn_t *conn, xmpp_stanza_t *stanza)
|
||||
}
|
||||
}
|
||||
|
||||
static int iq_reg2_cb(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int iq_reg2_cb(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
const char *type;
|
||||
|
||||
@@ -129,9 +127,7 @@ quit:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iq_reg_cb(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int iq_reg_cb(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
xmpp_reg_t *reg = (xmpp_reg_t *)userdata;
|
||||
xmpp_stanza_t *registered = NULL;
|
||||
@@ -166,9 +162,8 @@ quit:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_error(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int
|
||||
_handle_error(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
(void)stanza;
|
||||
(void)userdata;
|
||||
@@ -179,9 +174,9 @@ static int _handle_error(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_proceedtls_default(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int _handle_proceedtls_default(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata)
|
||||
{
|
||||
const char *name = xmpp_stanza_get_name(stanza);
|
||||
|
||||
@@ -201,8 +196,7 @@ static int _handle_proceedtls_default(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_missing_features(xmpp_conn_t *const conn,
|
||||
void *const userdata)
|
||||
static int _handle_missing_features(xmpp_conn_t *conn, void *userdata)
|
||||
{
|
||||
(void)userdata;
|
||||
|
||||
@@ -212,9 +206,8 @@ static int _handle_missing_features(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_features(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int
|
||||
_handle_features(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
xmpp_reg_t *reg = (xmpp_reg_t *)userdata;
|
||||
xmpp_ctx_t *ctx = reg->ctx;
|
||||
@@ -265,11 +258,11 @@ static int _handle_features(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static 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)
|
||||
static void conn_handler(xmpp_conn_t *conn,
|
||||
xmpp_conn_event_t status,
|
||||
int error,
|
||||
xmpp_stream_error_t *stream_error,
|
||||
void *userdata)
|
||||
{
|
||||
xmpp_reg_t *reg = (xmpp_reg_t *)userdata;
|
||||
int secured;
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
|
||||
#include <strophe.h>
|
||||
|
||||
int handle_reply(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
int handle_reply(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
xmpp_stanza_t *query, *item;
|
||||
const char *type, *name;
|
||||
@@ -51,11 +49,11 @@ int handle_reply(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
void conn_handler(xmpp_conn_t *conn,
|
||||
xmpp_conn_event_t status,
|
||||
int error,
|
||||
xmpp_stream_error_t *stream_error,
|
||||
void *userdata)
|
||||
{
|
||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||
xmpp_stanza_t *iq, *query;
|
||||
|
||||
@@ -160,7 +160,7 @@ exit:
|
||||
return cb;
|
||||
}
|
||||
|
||||
static int timedout(xmpp_conn_t *const conn, void *const userdata)
|
||||
static int timedout(xmpp_conn_t *conn, void *userdata)
|
||||
{
|
||||
(void)userdata;
|
||||
|
||||
@@ -170,9 +170,7 @@ static int timedout(xmpp_conn_t *const conn, void *const userdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int recv_vcard(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int recv_vcard(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
vcard_t *vc = userdata;
|
||||
vcard_cb_t cb;
|
||||
@@ -217,11 +215,11 @@ static void send_vcard_req(xmpp_conn_t *conn, const char *to, const char *id)
|
||||
xmpp_conn_get_bound_jid(conn), to, id);
|
||||
}
|
||||
|
||||
static 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)
|
||||
static void conn_handler(xmpp_conn_t *conn,
|
||||
xmpp_conn_event_t status,
|
||||
int error,
|
||||
xmpp_stream_error_t *stream_error,
|
||||
void *userdata)
|
||||
{
|
||||
vcard_t *vc = userdata;
|
||||
|
||||
|
||||
216
src/auth.c
216
src/auth.c
@@ -60,51 +60,43 @@
|
||||
#define HANDSHAKE_TIMEOUT 15000 /* 15 seconds */
|
||||
#endif
|
||||
|
||||
static void _auth(xmpp_conn_t *const conn);
|
||||
static void _auth(xmpp_conn_t *conn);
|
||||
static void _auth_legacy(xmpp_conn_t *conn);
|
||||
static void _handle_open_sasl(xmpp_conn_t *const conn);
|
||||
static void _handle_open_tls(xmpp_conn_t *const conn);
|
||||
static void _handle_open_sasl(xmpp_conn_t *conn);
|
||||
static void _handle_open_tls(xmpp_conn_t *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_component_auth(xmpp_conn_t *conn);
|
||||
static int _handle_component_hs_response(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata);
|
||||
|
||||
static int _handle_features_sasl(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata);
|
||||
static int _handle_sasl_result(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata);
|
||||
static int _handle_digestmd5_challenge(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata);
|
||||
static int _handle_digestmd5_rspauth(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata);
|
||||
static int _handle_scram_challenge(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata);
|
||||
static char *_make_scram_init_msg(xmpp_conn_t *const conn);
|
||||
static int
|
||||
_handle_features_sasl(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata);
|
||||
static int
|
||||
_handle_sasl_result(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata);
|
||||
static int _handle_digestmd5_challenge(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata);
|
||||
static int _handle_digestmd5_rspauth(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata);
|
||||
static int _handle_scram_challenge(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata);
|
||||
static char *_make_scram_init_msg(xmpp_conn_t *conn);
|
||||
|
||||
static int _handle_missing_features_sasl(xmpp_conn_t *const conn,
|
||||
void *const userdata);
|
||||
static int _handle_missing_bind(xmpp_conn_t *const conn, void *const userdata);
|
||||
static int _handle_bind(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata);
|
||||
static int _handle_session(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
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);
|
||||
static int _handle_missing_features_sasl(xmpp_conn_t *conn, void *userdata);
|
||||
static int _handle_missing_bind(xmpp_conn_t *conn, void *userdata);
|
||||
static int
|
||||
_handle_bind(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata);
|
||||
static int
|
||||
_handle_session(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata);
|
||||
static int _handle_missing_session(xmpp_conn_t *conn, void *userdata);
|
||||
static int _handle_missing_handshake(xmpp_conn_t *conn, void *userdata);
|
||||
|
||||
/* stream:error handler */
|
||||
static int _handle_error(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int
|
||||
_handle_error(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
xmpp_stanza_t *child;
|
||||
const char *name;
|
||||
@@ -199,8 +191,7 @@ static int _handle_error(xmpp_conn_t *const conn,
|
||||
}
|
||||
|
||||
/* stream:features handlers */
|
||||
static int _handle_missing_features(xmpp_conn_t *const conn,
|
||||
void *const userdata)
|
||||
static int _handle_missing_features(xmpp_conn_t *conn, void *userdata)
|
||||
{
|
||||
UNUSED(userdata);
|
||||
|
||||
@@ -212,9 +203,8 @@ static int _handle_missing_features(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_features(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int
|
||||
_handle_features(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
xmpp_stanza_t *child, *mech;
|
||||
const char *ns;
|
||||
@@ -252,6 +242,9 @@ static int _handle_features(xmpp_conn_t *const conn,
|
||||
|
||||
if (strcasecmp(text, "PLAIN") == 0)
|
||||
conn->sasl_support |= SASL_MASK_PLAIN;
|
||||
else if (strcasecmp(text, "EXTERNAL") == 0 &&
|
||||
conn->tls_client_cert)
|
||||
conn->sasl_support |= SASL_MASK_EXTERNAL;
|
||||
else if (strcasecmp(text, "DIGEST-MD5") == 0)
|
||||
conn->sasl_support |= SASL_MASK_DIGESTMD5;
|
||||
else if (strcasecmp(text, "SCRAM-SHA-1") == 0)
|
||||
@@ -279,7 +272,7 @@ static int _handle_features(xmpp_conn_t *const conn,
|
||||
|
||||
/* returns the correct auth id for a component or a client.
|
||||
* returned string must be freed by caller */
|
||||
static char *_get_authid(xmpp_conn_t *const conn)
|
||||
static char *_get_authid(xmpp_conn_t *conn)
|
||||
{
|
||||
char *authid = NULL;
|
||||
|
||||
@@ -293,9 +286,9 @@ static char *_get_authid(xmpp_conn_t *const conn)
|
||||
return authid;
|
||||
}
|
||||
|
||||
static int _handle_proceedtls_default(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int _handle_proceedtls_default(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
@@ -319,9 +312,8 @@ static int _handle_proceedtls_default(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_sasl_result(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int
|
||||
_handle_sasl_result(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
@@ -355,9 +347,9 @@ static int _handle_sasl_result(xmpp_conn_t *const conn,
|
||||
}
|
||||
|
||||
/* handle the challenge phase of digest auth */
|
||||
static int _handle_digestmd5_challenge(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int _handle_digestmd5_challenge(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata)
|
||||
{
|
||||
char *text;
|
||||
char *response;
|
||||
@@ -414,9 +406,9 @@ static int _handle_digestmd5_challenge(xmpp_conn_t *const conn,
|
||||
}
|
||||
|
||||
/* handle the rspauth phase of digest auth */
|
||||
static int _handle_digestmd5_rspauth(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int _handle_digestmd5_rspauth(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata)
|
||||
{
|
||||
xmpp_stanza_t *auth;
|
||||
const char *name;
|
||||
@@ -451,9 +443,9 @@ struct scram_user_data {
|
||||
};
|
||||
|
||||
/* handle the challenge phase of SCRAM-SHA-1 auth */
|
||||
static int _handle_scram_challenge(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int _handle_scram_challenge(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata)
|
||||
{
|
||||
char *text;
|
||||
char *response;
|
||||
@@ -532,7 +524,7 @@ err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *_make_scram_init_msg(xmpp_conn_t *const conn)
|
||||
static char *_make_scram_init_msg(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_ctx_t *ctx = conn->ctx;
|
||||
size_t message_len;
|
||||
@@ -555,7 +547,7 @@ static char *_make_scram_init_msg(xmpp_conn_t *const conn)
|
||||
return message;
|
||||
}
|
||||
|
||||
static xmpp_stanza_t *_make_starttls(xmpp_conn_t *const conn)
|
||||
static xmpp_stanza_t *_make_starttls(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_stanza_t *starttls;
|
||||
|
||||
@@ -569,8 +561,7 @@ static xmpp_stanza_t *_make_starttls(xmpp_conn_t *const conn)
|
||||
return starttls;
|
||||
}
|
||||
|
||||
static xmpp_stanza_t *_make_sasl_auth(xmpp_conn_t *const conn,
|
||||
const char *const mechanism)
|
||||
static xmpp_stanza_t *_make_sasl_auth(xmpp_conn_t *conn, const char *mechanism)
|
||||
{
|
||||
xmpp_stanza_t *auth;
|
||||
|
||||
@@ -590,7 +581,7 @@ static xmpp_stanza_t *_make_sasl_auth(xmpp_conn_t *const conn,
|
||||
* this will get called again until one auth method succeeds or every
|
||||
* method fails
|
||||
*/
|
||||
static void _auth(xmpp_conn_t *const conn)
|
||||
static void _auth(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_stanza_t *auth;
|
||||
xmpp_stanza_t *authdata;
|
||||
@@ -663,6 +654,49 @@ static void _auth(xmpp_conn_t *const conn)
|
||||
|
||||
/* SASL ANONYMOUS was tried, unset flag */
|
||||
conn->sasl_support &= ~SASL_MASK_ANONYMOUS;
|
||||
} else if (conn->sasl_support & SASL_MASK_EXTERNAL) {
|
||||
/* more crap here */
|
||||
auth = _make_sasl_auth(conn, "EXTERNAL");
|
||||
if (!auth) {
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
authdata = xmpp_stanza_new(conn->ctx);
|
||||
if (!authdata) {
|
||||
xmpp_stanza_release(auth);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
str = tls_id_on_xmppaddr(conn, 0);
|
||||
if (!str || (tls_id_on_xmppaddr_num(conn) == 1 &&
|
||||
strcmp(str, conn->jid) == 0)) {
|
||||
xmpp_stanza_set_text(authdata, "=");
|
||||
} else {
|
||||
xmpp_free(conn->ctx, str);
|
||||
str = xmpp_base64_encode(conn->ctx, (void *)conn->jid,
|
||||
strlen(conn->jid));
|
||||
if (!str) {
|
||||
xmpp_stanza_release(authdata);
|
||||
xmpp_stanza_release(auth);
|
||||
disconnect_mem_error(conn);
|
||||
return;
|
||||
}
|
||||
xmpp_stanza_set_text(authdata, str);
|
||||
}
|
||||
xmpp_free(conn->ctx, str);
|
||||
|
||||
xmpp_stanza_add_child(auth, authdata);
|
||||
xmpp_stanza_release(authdata);
|
||||
|
||||
handler_add(conn, _handle_sasl_result, XMPP_NS_SASL, NULL, NULL,
|
||||
"EXTERNAL");
|
||||
|
||||
xmpp_send(conn, auth);
|
||||
xmpp_stanza_release(auth);
|
||||
|
||||
/* SASL EXTERNAL was tried, unset flag */
|
||||
conn->sasl_support &= ~SASL_MASK_EXTERNAL;
|
||||
} else if (anonjid) {
|
||||
xmpp_error(conn->ctx, "auth",
|
||||
"No node in JID, and SASL ANONYMOUS unsupported.");
|
||||
@@ -796,7 +830,7 @@ static void _auth(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
*/
|
||||
void auth_handle_open(xmpp_conn_t *const conn)
|
||||
void auth_handle_open(xmpp_conn_t *conn)
|
||||
{
|
||||
/* reset all timed handlers */
|
||||
handler_reset_timed(conn, 0);
|
||||
@@ -812,7 +846,7 @@ void auth_handle_open(xmpp_conn_t *const conn)
|
||||
}
|
||||
|
||||
/* called when stream:stream tag received after TLS establishment */
|
||||
static void _handle_open_tls(xmpp_conn_t *const conn)
|
||||
static void _handle_open_tls(xmpp_conn_t *conn)
|
||||
{
|
||||
/* setup handlers for incoming <stream:features> */
|
||||
handler_add(conn, _handle_features, XMPP_NS_STREAMS, "features", NULL,
|
||||
@@ -821,7 +855,7 @@ static void _handle_open_tls(xmpp_conn_t *const conn)
|
||||
}
|
||||
|
||||
/* called when stream:stream tag received after SASL auth */
|
||||
static void _handle_open_sasl(xmpp_conn_t *const conn)
|
||||
static void _handle_open_sasl(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_debug(conn->ctx, "xmpp", "Reopened stream successfully.");
|
||||
|
||||
@@ -832,9 +866,8 @@ static void _handle_open_sasl(xmpp_conn_t *const conn)
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int _handle_features_sasl(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int
|
||||
_handle_features_sasl(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
xmpp_stanza_t *bind, *session, *iq, *res, *text, *opt;
|
||||
const char *ns;
|
||||
@@ -939,8 +972,7 @@ static int _handle_features_sasl(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_missing_features_sasl(xmpp_conn_t *const conn,
|
||||
void *const userdata)
|
||||
static int _handle_missing_features_sasl(xmpp_conn_t *conn, void *userdata)
|
||||
{
|
||||
UNUSED(userdata);
|
||||
|
||||
@@ -951,9 +983,8 @@ static int _handle_missing_features_sasl(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_bind(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int
|
||||
_handle_bind(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
const char *type;
|
||||
xmpp_stanza_t *iq, *session;
|
||||
@@ -1025,7 +1056,7 @@ static int _handle_bind(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_missing_bind(xmpp_conn_t *const conn, void *const userdata)
|
||||
static int _handle_missing_bind(xmpp_conn_t *conn, void *userdata)
|
||||
{
|
||||
UNUSED(userdata);
|
||||
|
||||
@@ -1034,9 +1065,8 @@ static int _handle_missing_bind(xmpp_conn_t *const conn, void *const userdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_session(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int
|
||||
_handle_session(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
const char *type;
|
||||
|
||||
@@ -1065,8 +1095,7 @@ static int _handle_session(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_missing_session(xmpp_conn_t *const conn,
|
||||
void *const userdata)
|
||||
static int _handle_missing_session(xmpp_conn_t *conn, void *userdata)
|
||||
{
|
||||
UNUSED(userdata);
|
||||
|
||||
@@ -1075,7 +1104,7 @@ static int _handle_missing_session(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_missing_legacy(xmpp_conn_t *const conn, void *const userdata)
|
||||
static int _handle_missing_legacy(xmpp_conn_t *conn, void *userdata)
|
||||
{
|
||||
UNUSED(userdata);
|
||||
|
||||
@@ -1086,9 +1115,8 @@ static int _handle_missing_legacy(xmpp_conn_t *const conn, void *const userdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_legacy(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata)
|
||||
static int
|
||||
_handle_legacy(xmpp_conn_t *conn, xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
const char *type;
|
||||
const char *name;
|
||||
@@ -1219,7 +1247,7 @@ err:
|
||||
disconnect_mem_error(conn);
|
||||
}
|
||||
|
||||
void auth_handle_component_open(xmpp_conn_t *const conn)
|
||||
void auth_handle_component_open(xmpp_conn_t *conn)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -1239,7 +1267,7 @@ void auth_handle_component_open(xmpp_conn_t *const conn)
|
||||
}
|
||||
|
||||
/* Will compute SHA1 and authenticate the component to the server */
|
||||
int _handle_component_auth(xmpp_conn_t *const conn)
|
||||
int _handle_component_auth(xmpp_conn_t *conn)
|
||||
{
|
||||
uint8_t md_value[SHA1_DIGEST_SIZE];
|
||||
SHA1_CTX mdctx;
|
||||
@@ -1289,9 +1317,9 @@ int _handle_component_auth(xmpp_conn_t *const conn)
|
||||
/* 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)
|
||||
int _handle_component_hs_response(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
@@ -1321,7 +1349,7 @@ int _handle_component_hs_response(xmpp_conn_t *const conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _handle_missing_handshake(xmpp_conn_t *const conn, void *const userdata)
|
||||
int _handle_missing_handshake(xmpp_conn_t *conn, void *userdata)
|
||||
{
|
||||
UNUSED(userdata);
|
||||
|
||||
@@ -1330,7 +1358,7 @@ int _handle_missing_handshake(xmpp_conn_t *const conn, void *const userdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void auth_handle_open_raw(xmpp_conn_t *const conn)
|
||||
void auth_handle_open_raw(xmpp_conn_t *conn)
|
||||
{
|
||||
handler_reset_timed(conn, 0);
|
||||
/* user handlers are not called before authentication is completed. */
|
||||
@@ -1338,7 +1366,7 @@ void auth_handle_open_raw(xmpp_conn_t *const conn)
|
||||
conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata);
|
||||
}
|
||||
|
||||
void auth_handle_open_stub(xmpp_conn_t *const conn)
|
||||
void auth_handle_open_stub(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_warn(conn->ctx, "auth", "Stub callback is called.");
|
||||
}
|
||||
|
||||
87
src/common.h
87
src/common.h
@@ -87,33 +87,21 @@ struct _xmpp_ctx_t {
|
||||
};
|
||||
|
||||
/* convenience functions for accessing the context */
|
||||
void *xmpp_alloc(const xmpp_ctx_t *const ctx, const size_t size);
|
||||
void *xmpp_realloc(const xmpp_ctx_t *const ctx, void *p, const size_t size);
|
||||
char *xmpp_strdup(const xmpp_ctx_t *const ctx, const char *const s);
|
||||
void *xmpp_alloc(const xmpp_ctx_t *ctx, size_t size);
|
||||
void *xmpp_realloc(const xmpp_ctx_t *ctx, void *p, size_t size);
|
||||
char *xmpp_strdup(const xmpp_ctx_t *ctx, const char *s);
|
||||
|
||||
void xmpp_log(const xmpp_ctx_t *const ctx,
|
||||
void xmpp_log(const xmpp_ctx_t *ctx,
|
||||
const xmpp_log_level_t level,
|
||||
const char *const area,
|
||||
const char *const fmt,
|
||||
const char *area,
|
||||
const char *fmt,
|
||||
va_list ap);
|
||||
|
||||
/* wrappers for xmpp_log at specific levels */
|
||||
void xmpp_error(const xmpp_ctx_t *const ctx,
|
||||
const char *const area,
|
||||
const char *const fmt,
|
||||
...);
|
||||
void xmpp_warn(const xmpp_ctx_t *const ctx,
|
||||
const char *const area,
|
||||
const char *const fmt,
|
||||
...);
|
||||
void xmpp_info(const xmpp_ctx_t *const ctx,
|
||||
const char *const area,
|
||||
const char *const fmt,
|
||||
...);
|
||||
void xmpp_debug(const xmpp_ctx_t *const ctx,
|
||||
const char *const area,
|
||||
const char *const fmt,
|
||||
...);
|
||||
void xmpp_error(const xmpp_ctx_t *ctx, const char *area, const char *fmt, ...);
|
||||
void xmpp_warn(const xmpp_ctx_t *ctx, const char *area, const char *fmt, ...);
|
||||
void xmpp_info(const xmpp_ctx_t *ctx, const char *area, const char *fmt, ...);
|
||||
void xmpp_debug(const xmpp_ctx_t *ctx, const char *area, const char *fmt, ...);
|
||||
|
||||
/** connection **/
|
||||
|
||||
@@ -143,6 +131,7 @@ struct _xmpp_send_queue_t {
|
||||
#define SASL_MASK_SCRAMSHA1 (1 << 3)
|
||||
#define SASL_MASK_SCRAMSHA256 (1 << 4)
|
||||
#define SASL_MASK_SCRAMSHA512 (1 << 5)
|
||||
#define SASL_MASK_EXTERNAL (1 << 6)
|
||||
|
||||
#define SASL_MASK_SCRAM \
|
||||
(SASL_MASK_SCRAMSHA1 | SASL_MASK_SCRAMSHA256 | SASL_MASK_SCRAMSHA512)
|
||||
@@ -153,7 +142,7 @@ enum {
|
||||
XMPP_PORT_COMPONENT = 5347,
|
||||
};
|
||||
|
||||
typedef void (*xmpp_open_handler)(xmpp_conn_t *const conn);
|
||||
typedef void (*xmpp_open_handler)(xmpp_conn_t *conn);
|
||||
|
||||
struct _xmpp_conn_t {
|
||||
unsigned int ref;
|
||||
@@ -176,6 +165,8 @@ struct _xmpp_conn_t {
|
||||
int tls_mandatory;
|
||||
int tls_legacy_ssl;
|
||||
int tls_trust;
|
||||
char *tls_client_cert;
|
||||
char *tls_client_key;
|
||||
int tls_failed; /* set when tls fails, so we don't try again */
|
||||
int sasl_support; /* if true, field is a bitfield of supported
|
||||
mechanisms */
|
||||
@@ -225,13 +216,13 @@ struct _xmpp_conn_t {
|
||||
xmpp_handlist_t *handlers;
|
||||
};
|
||||
|
||||
void conn_disconnect(xmpp_conn_t *const conn);
|
||||
void conn_disconnect_clean(xmpp_conn_t *const conn);
|
||||
void conn_established(xmpp_conn_t *const conn);
|
||||
void conn_open_stream(xmpp_conn_t *const conn);
|
||||
int conn_tls_start(xmpp_conn_t *const conn);
|
||||
void conn_prepare_reset(xmpp_conn_t *const conn, xmpp_open_handler handler);
|
||||
void conn_parser_reset(xmpp_conn_t *const conn);
|
||||
void conn_disconnect(xmpp_conn_t *conn);
|
||||
void conn_disconnect_clean(xmpp_conn_t *conn);
|
||||
void conn_established(xmpp_conn_t *conn);
|
||||
void conn_open_stream(xmpp_conn_t *conn);
|
||||
int conn_tls_start(xmpp_conn_t *conn);
|
||||
void conn_prepare_reset(xmpp_conn_t *conn, xmpp_open_handler handler);
|
||||
void conn_parser_reset(xmpp_conn_t *conn);
|
||||
|
||||
typedef enum {
|
||||
XMPP_STANZA_UNKNOWN,
|
||||
@@ -256,32 +247,32 @@ struct _xmpp_stanza_t {
|
||||
};
|
||||
|
||||
/* handler management */
|
||||
void handler_fire_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza);
|
||||
uint64_t handler_fire_timed(xmpp_ctx_t *const ctx);
|
||||
void handler_fire_stanza(xmpp_conn_t *conn, xmpp_stanza_t *stanza);
|
||||
uint64_t handler_fire_timed(xmpp_ctx_t *ctx);
|
||||
void handler_reset_timed(xmpp_conn_t *conn, int user_only);
|
||||
void handler_add_timed(xmpp_conn_t *const conn,
|
||||
void handler_add_timed(xmpp_conn_t *conn,
|
||||
xmpp_timed_handler handler,
|
||||
const unsigned long period,
|
||||
void *const userdata);
|
||||
void handler_add_id(xmpp_conn_t *const conn,
|
||||
unsigned long period,
|
||||
void *userdata);
|
||||
void handler_add_id(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const id,
|
||||
void *const userdata);
|
||||
void handler_add(xmpp_conn_t *const conn,
|
||||
const char *id,
|
||||
void *userdata);
|
||||
void handler_add(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const ns,
|
||||
const char *const name,
|
||||
const char *const type,
|
||||
void *const userdata);
|
||||
const char *ns,
|
||||
const char *name,
|
||||
const char *type,
|
||||
void *userdata);
|
||||
void handler_system_delete_all(xmpp_conn_t *conn);
|
||||
|
||||
/* utility functions */
|
||||
void disconnect_mem_error(xmpp_conn_t *const conn);
|
||||
void disconnect_mem_error(xmpp_conn_t *conn);
|
||||
|
||||
/* auth functions */
|
||||
void auth_handle_open(xmpp_conn_t *const conn);
|
||||
void auth_handle_component_open(xmpp_conn_t *const conn);
|
||||
void auth_handle_open_raw(xmpp_conn_t *const conn);
|
||||
void auth_handle_open_stub(xmpp_conn_t *const conn);
|
||||
void auth_handle_open(xmpp_conn_t *conn);
|
||||
void auth_handle_component_open(xmpp_conn_t *conn);
|
||||
void auth_handle_open_raw(xmpp_conn_t *conn);
|
||||
void auth_handle_open_stub(xmpp_conn_t *conn);
|
||||
|
||||
#endif /* __LIBSTROPHE_COMMON_H__ */
|
||||
|
||||
280
src/conn.c
280
src/conn.c
@@ -48,10 +48,13 @@
|
||||
#define CONNECT_TIMEOUT 5000 /* 5 seconds */
|
||||
#endif
|
||||
|
||||
static int _disconnect_cleanup(xmpp_conn_t *const conn, void *const userdata);
|
||||
static char *_conn_build_stream_tag(xmpp_conn_t *const conn,
|
||||
static int _disconnect_cleanup(xmpp_conn_t *conn, void *userdata);
|
||||
static char *_conn_build_stream_tag(xmpp_conn_t *conn,
|
||||
char **attributes,
|
||||
size_t attributes_len);
|
||||
static int _conn_open_stream_with_attributes(xmpp_conn_t *conn,
|
||||
char **attributes,
|
||||
size_t attributes_len);
|
||||
static void _conn_attributes_new(xmpp_conn_t *conn,
|
||||
char **attrs,
|
||||
char ***attributes,
|
||||
@@ -59,24 +62,21 @@ static void _conn_attributes_new(xmpp_conn_t *conn,
|
||||
static void _conn_attributes_destroy(xmpp_conn_t *conn,
|
||||
char **attributes,
|
||||
size_t attributes_len);
|
||||
static void
|
||||
_handle_stream_start(char *name, char **attrs, void *const userdata);
|
||||
static void _handle_stream_end(char *name, void *const userdata);
|
||||
static void _handle_stream_stanza(xmpp_stanza_t *stanza, void *const userdata);
|
||||
static unsigned short _conn_default_port(xmpp_conn_t *const conn,
|
||||
static void _handle_stream_start(char *name, char **attrs, void *userdata);
|
||||
static void _handle_stream_end(char *name, void *userdata);
|
||||
static void _handle_stream_stanza(xmpp_stanza_t *stanza, void *userdata);
|
||||
static unsigned short _conn_default_port(xmpp_conn_t *conn,
|
||||
xmpp_conn_type_t type);
|
||||
static void _conn_reset(xmpp_conn_t *const conn);
|
||||
static int _conn_connect(xmpp_conn_t *const conn,
|
||||
const char *const domain,
|
||||
const char *const host,
|
||||
static void _conn_reset(xmpp_conn_t *conn);
|
||||
static int _conn_connect(xmpp_conn_t *conn,
|
||||
const char *domain,
|
||||
const char *host,
|
||||
unsigned short port,
|
||||
xmpp_conn_type_t type,
|
||||
xmpp_conn_handler callback,
|
||||
void *const userdata);
|
||||
void *userdata);
|
||||
|
||||
void xmpp_send_error(xmpp_conn_t *const conn,
|
||||
xmpp_error_type_t const type,
|
||||
char *const text)
|
||||
void xmpp_send_error(xmpp_conn_t *conn, xmpp_error_type_t type, char *text)
|
||||
{
|
||||
xmpp_stanza_t *error = xmpp_error_new(conn->ctx, type, text);
|
||||
|
||||
@@ -93,7 +93,7 @@ void xmpp_send_error(xmpp_conn_t *const conn,
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t *const ctx)
|
||||
xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t *ctx)
|
||||
{
|
||||
xmpp_conn_t *conn = NULL;
|
||||
xmpp_connlist_t *tail, *item;
|
||||
@@ -143,6 +143,8 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t *const ctx)
|
||||
conn->tls_legacy_ssl = 0;
|
||||
conn->tls_trust = 0;
|
||||
conn->tls_failed = 0;
|
||||
conn->tls_client_cert = NULL;
|
||||
conn->tls_client_key = NULL;
|
||||
conn->sasl_support = 0;
|
||||
conn->auth_legacy_enabled = 0;
|
||||
conn->secured = 0;
|
||||
@@ -201,7 +203,7 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t *const ctx)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t *const conn)
|
||||
xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t *conn)
|
||||
{
|
||||
conn->ref++;
|
||||
return conn;
|
||||
@@ -219,7 +221,7 @@ xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
void xmpp_conn_set_keepalive(xmpp_conn_t *const conn, int timeout, int interval)
|
||||
void xmpp_conn_set_keepalive(xmpp_conn_t *conn, int timeout, int interval)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -245,7 +247,7 @@ void xmpp_conn_set_keepalive(xmpp_conn_t *const conn, int timeout, int interval)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_conn_release(xmpp_conn_t *const conn)
|
||||
int xmpp_conn_release(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_ctx_t *ctx;
|
||||
xmpp_connlist_t *item, *prev;
|
||||
@@ -338,6 +340,10 @@ int xmpp_conn_release(xmpp_conn_t *const conn)
|
||||
xmpp_free(ctx, conn->pass);
|
||||
if (conn->lang)
|
||||
xmpp_free(ctx, conn->lang);
|
||||
if (conn->tls_client_cert)
|
||||
xmpp_free(ctx, conn->tls_client_cert);
|
||||
if (conn->tls_client_key)
|
||||
xmpp_free(ctx, conn->tls_client_key);
|
||||
xmpp_free(ctx, conn);
|
||||
released = 1;
|
||||
}
|
||||
@@ -353,7 +359,7 @@ int xmpp_conn_release(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
const char *xmpp_conn_get_jid(const xmpp_conn_t *const conn)
|
||||
const char *xmpp_conn_get_jid(const xmpp_conn_t *conn)
|
||||
{
|
||||
return conn->jid;
|
||||
}
|
||||
@@ -371,7 +377,7 @@ const char *xmpp_conn_get_jid(const xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
const char *xmpp_conn_get_bound_jid(const xmpp_conn_t *const conn)
|
||||
const char *xmpp_conn_get_bound_jid(const xmpp_conn_t *conn)
|
||||
{
|
||||
return conn->bound_jid;
|
||||
}
|
||||
@@ -387,13 +393,65 @@ const char *xmpp_conn_get_bound_jid(const xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
void xmpp_conn_set_jid(xmpp_conn_t *const conn, const char *const jid)
|
||||
void xmpp_conn_set_jid(xmpp_conn_t *conn, const char *jid)
|
||||
{
|
||||
if (conn->jid)
|
||||
xmpp_free(conn->ctx, conn->jid);
|
||||
conn->jid = xmpp_strdup(conn->ctx, jid);
|
||||
}
|
||||
|
||||
/** Set the Client Certificate and Private Key that will be bound to the
|
||||
* connection. If any of the both was previously set, it will be discarded.
|
||||
* This should not be used after a connection is created. The function will
|
||||
* make a copy of the strings passed in.
|
||||
* Currently only non-encrypted Private Keys are supported.
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
* @param cert path to a certificate file
|
||||
* @param key path to a private key file
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
void xmpp_conn_set_client_cert(xmpp_conn_t *const conn,
|
||||
const char *const cert,
|
||||
const char *const key)
|
||||
{
|
||||
xmpp_debug(conn->ctx, "conn", "set client cert %s %s", cert, key);
|
||||
if (conn->tls_client_cert)
|
||||
xmpp_free(conn->ctx, conn->tls_client_cert);
|
||||
conn->tls_client_cert = xmpp_strdup(conn->ctx, cert);
|
||||
if (conn->tls_client_key)
|
||||
xmpp_free(conn->ctx, conn->tls_client_key);
|
||||
conn->tls_client_key = xmpp_strdup(conn->ctx, key);
|
||||
}
|
||||
|
||||
/** Get the number of xmppAddr entries in the client certificate.
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
*
|
||||
* @return the number of xmppAddr entries in the client certificate
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
unsigned int xmpp_conn_cert_xmppaddr_num(xmpp_conn_t *const conn)
|
||||
{
|
||||
return tls_id_on_xmppaddr_num(conn);
|
||||
}
|
||||
|
||||
/** Get a specific xmppAddr entry.
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
* @param n the index of the entry, starting at 0
|
||||
*
|
||||
* @return a string containing the xmppAddr or NULL if n is out of range
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
char *xmpp_conn_cert_xmppaddr(xmpp_conn_t *const conn, unsigned int n)
|
||||
{
|
||||
return tls_id_on_xmppaddr(conn, n);
|
||||
}
|
||||
|
||||
/** Get the password used for authentication of a connection.
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
@@ -402,7 +460,7 @@ void xmpp_conn_set_jid(xmpp_conn_t *const conn, const char *const jid)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
const char *xmpp_conn_get_pass(const xmpp_conn_t *const conn)
|
||||
const char *xmpp_conn_get_pass(const xmpp_conn_t *conn)
|
||||
{
|
||||
return conn->pass;
|
||||
}
|
||||
@@ -416,7 +474,7 @@ const char *xmpp_conn_get_pass(const xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
void xmpp_conn_set_pass(xmpp_conn_t *const conn, const char *const pass)
|
||||
void xmpp_conn_set_pass(xmpp_conn_t *conn, const char *pass)
|
||||
{
|
||||
if (conn->pass)
|
||||
xmpp_free(conn->ctx, conn->pass);
|
||||
@@ -430,7 +488,7 @@ void xmpp_conn_set_pass(xmpp_conn_t *const conn, const char *const pass)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
xmpp_ctx_t *xmpp_conn_get_context(xmpp_conn_t *const conn)
|
||||
xmpp_ctx_t *xmpp_conn_get_context(xmpp_conn_t *conn)
|
||||
{
|
||||
return conn->ctx;
|
||||
}
|
||||
@@ -456,11 +514,11 @@ xmpp_ctx_t *xmpp_conn_get_context(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_connect_client(xmpp_conn_t *const conn,
|
||||
const char *const altdomain,
|
||||
int xmpp_connect_client(xmpp_conn_t *conn,
|
||||
const char *altdomain,
|
||||
unsigned short altport,
|
||||
xmpp_conn_handler callback,
|
||||
void *const userdata)
|
||||
void *userdata)
|
||||
{
|
||||
resolver_srv_rr_t *srv_rr_list = NULL;
|
||||
resolver_srv_rr_t *rr;
|
||||
@@ -470,6 +528,25 @@ int xmpp_connect_client(xmpp_conn_t *const conn,
|
||||
int found = XMPP_DOMAIN_NOT_FOUND;
|
||||
int rc;
|
||||
|
||||
if (!conn->jid && conn->tls_client_cert) {
|
||||
if (tls_id_on_xmppaddr_num(conn) != 1) {
|
||||
xmpp_debug(conn->ctx, "xmpp",
|
||||
"Client certificate contains multiple or no xmppAddr "
|
||||
"and no JID was given to be used.");
|
||||
return XMPP_EINVOP;
|
||||
}
|
||||
conn->jid = tls_id_on_xmppaddr(conn, 0);
|
||||
if (!conn->jid)
|
||||
return XMPP_EMEM;
|
||||
xmpp_debug(conn->ctx, "xmpp", "Use jid %s from id-on-xmppAddr.",
|
||||
conn->jid);
|
||||
}
|
||||
|
||||
if (!conn->jid) {
|
||||
xmpp_error(conn->ctx, "xmpp", "JID is not set.");
|
||||
return XMPP_EINVOP;
|
||||
}
|
||||
|
||||
domain = xmpp_jid_domain(conn->ctx, conn->jid);
|
||||
if (!domain)
|
||||
return XMPP_EMEM;
|
||||
@@ -536,11 +613,11 @@ int xmpp_connect_client(xmpp_conn_t *const conn,
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_connect_component(xmpp_conn_t *const conn,
|
||||
const char *const server,
|
||||
int xmpp_connect_component(xmpp_conn_t *conn,
|
||||
const char *server,
|
||||
unsigned short port,
|
||||
xmpp_conn_handler callback,
|
||||
void *const userdata)
|
||||
void *userdata)
|
||||
{
|
||||
/* The server domain, jid and password MUST be specified. */
|
||||
if (!(server && conn->jid && conn->pass))
|
||||
@@ -583,18 +660,18 @@ int xmpp_connect_component(xmpp_conn_t *const conn,
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_connect_raw(xmpp_conn_t *const conn,
|
||||
const char *const altdomain,
|
||||
int xmpp_connect_raw(xmpp_conn_t *conn,
|
||||
const char *altdomain,
|
||||
unsigned short altport,
|
||||
xmpp_conn_handler callback,
|
||||
void *const userdata)
|
||||
void *userdata)
|
||||
{
|
||||
conn->is_raw = 1;
|
||||
return xmpp_connect_client(conn, altdomain, altport, callback, userdata);
|
||||
}
|
||||
|
||||
/* Called when tcp connection is established. */
|
||||
void conn_established(xmpp_conn_t *const conn)
|
||||
void conn_established(xmpp_conn_t *conn)
|
||||
{
|
||||
if (conn->tls_legacy_ssl && !conn->is_raw) {
|
||||
xmpp_debug(conn->ctx, "xmpp", "using legacy SSL connection");
|
||||
@@ -628,7 +705,7 @@ void conn_established(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_conn_open_stream_default(xmpp_conn_t *const conn)
|
||||
int xmpp_conn_open_stream_default(xmpp_conn_t *conn)
|
||||
{
|
||||
if (!conn->is_raw)
|
||||
return XMPP_EINVOP;
|
||||
@@ -655,24 +732,16 @@ int xmpp_conn_open_stream_default(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_conn_open_stream(xmpp_conn_t *const conn,
|
||||
int xmpp_conn_open_stream(xmpp_conn_t *conn,
|
||||
char **attributes,
|
||||
size_t attributes_len)
|
||||
{
|
||||
char *tag;
|
||||
|
||||
if (!conn->is_raw)
|
||||
return XMPP_EINVOP;
|
||||
|
||||
tag = _conn_build_stream_tag(conn, attributes, attributes_len);
|
||||
if (!tag)
|
||||
return XMPP_EMEM;
|
||||
|
||||
conn_prepare_reset(conn, auth_handle_open_raw);
|
||||
xmpp_send_raw_string(conn, "<?xml version=\"1.0\"?>%s", tag);
|
||||
xmpp_free(conn->ctx, tag);
|
||||
|
||||
return XMPP_EOK;
|
||||
return _conn_open_stream_with_attributes(conn, attributes, attributes_len);
|
||||
}
|
||||
|
||||
/** Start synchronous TLS handshake with the server.
|
||||
@@ -681,7 +750,7 @@ int xmpp_conn_open_stream(xmpp_conn_t *const conn,
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_conn_tls_start(xmpp_conn_t *const conn)
|
||||
int xmpp_conn_tls_start(xmpp_conn_t *conn)
|
||||
{
|
||||
return conn_tls_start(conn);
|
||||
}
|
||||
@@ -692,7 +761,7 @@ int xmpp_conn_tls_start(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
*/
|
||||
void conn_disconnect_clean(xmpp_conn_t *const conn)
|
||||
void conn_disconnect_clean(xmpp_conn_t *conn)
|
||||
{
|
||||
/* remove the timed handler */
|
||||
xmpp_timed_handler_delete(conn, _disconnect_cleanup);
|
||||
@@ -706,7 +775,7 @@ void conn_disconnect_clean(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
*/
|
||||
void conn_disconnect(xmpp_conn_t *const conn)
|
||||
void conn_disconnect(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_debug(conn->ctx, "xmpp", "Closing socket.");
|
||||
conn->state = XMPP_STATE_DISCONNECTED;
|
||||
@@ -724,14 +793,14 @@ void conn_disconnect(xmpp_conn_t *const conn)
|
||||
|
||||
/* prepares a parser reset. this is called from handlers. we can't
|
||||
* reset the parser immediately as it is not re-entrant. */
|
||||
void conn_prepare_reset(xmpp_conn_t *const conn, xmpp_open_handler handler)
|
||||
void conn_prepare_reset(xmpp_conn_t *conn, xmpp_open_handler handler)
|
||||
{
|
||||
conn->reset_parser = 1;
|
||||
conn->open_handler = handler;
|
||||
}
|
||||
|
||||
/* reset the parser */
|
||||
void conn_parser_reset(xmpp_conn_t *const conn)
|
||||
void conn_parser_reset(xmpp_conn_t *conn)
|
||||
{
|
||||
conn->reset_parser = 0;
|
||||
parser_reset(conn->parser);
|
||||
@@ -746,7 +815,7 @@ void conn_parser_reset(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
void xmpp_disconnect(xmpp_conn_t *const conn)
|
||||
void xmpp_disconnect(xmpp_conn_t *conn)
|
||||
{
|
||||
if (conn->state != XMPP_STATE_CONNECTING &&
|
||||
conn->state != XMPP_STATE_CONNECTED)
|
||||
@@ -772,7 +841,7 @@ void xmpp_disconnect(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
void xmpp_send_raw_string(xmpp_conn_t *const conn, const char *const fmt, ...)
|
||||
void xmpp_send_raw_string(xmpp_conn_t *conn, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
size_t len;
|
||||
@@ -821,9 +890,7 @@ void xmpp_send_raw_string(xmpp_conn_t *const conn, const char *const fmt, ...)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
void xmpp_send_raw(xmpp_conn_t *const conn,
|
||||
const char *const data,
|
||||
const size_t len)
|
||||
void xmpp_send_raw(xmpp_conn_t *conn, const char *data, size_t len)
|
||||
{
|
||||
xmpp_send_queue_t *item;
|
||||
|
||||
@@ -867,7 +934,7 @@ void xmpp_send_raw(xmpp_conn_t *const conn,
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
void xmpp_send(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
|
||||
void xmpp_send(xmpp_conn_t *conn, xmpp_stanza_t *stanza)
|
||||
{
|
||||
char *buf;
|
||||
size_t len;
|
||||
@@ -887,22 +954,36 @@ void xmpp_send(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
*/
|
||||
void conn_open_stream(xmpp_conn_t *const conn)
|
||||
void conn_open_stream(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_send_raw_string(conn,
|
||||
"<?xml version=\"1.0\"?>"
|
||||
"<stream:stream to=\"%s\" "
|
||||
"xml:lang=\"%s\" "
|
||||
"version=\"1.0\" "
|
||||
"xmlns=\"%s\" "
|
||||
"xmlns:stream=\"%s\">",
|
||||
conn->domain, conn->lang,
|
||||
conn->type == XMPP_CLIENT ? XMPP_NS_CLIENT
|
||||
: XMPP_NS_COMPONENT,
|
||||
XMPP_NS_STREAMS);
|
||||
size_t attributes_len;
|
||||
int rc;
|
||||
char *from = NULL;
|
||||
char *ns = conn->type == XMPP_CLIENT ? XMPP_NS_CLIENT : XMPP_NS_COMPONENT;
|
||||
char *attributes[12] = {
|
||||
"to", conn->domain, "xml:lang", conn->lang,
|
||||
"version", "1.0", "xmlns", ns,
|
||||
"xmlns:stream", XMPP_NS_STREAMS, "from", NULL};
|
||||
|
||||
attributes_len = ARRAY_SIZE(attributes);
|
||||
if (conn->tls && conn->jid && strchr(conn->jid, '@') != NULL)
|
||||
from = xmpp_jid_bare(conn->ctx, conn->jid);
|
||||
|
||||
if (from)
|
||||
attributes[attributes_len - 1] = from;
|
||||
else
|
||||
attributes_len -= 2;
|
||||
|
||||
rc = _conn_open_stream_with_attributes(conn, attributes, attributes_len);
|
||||
if (rc != XMPP_EOK) {
|
||||
xmpp_error(conn->ctx, "conn", "Cannot build stream tag: memory error");
|
||||
conn_disconnect(conn);
|
||||
}
|
||||
if (from)
|
||||
xmpp_free(conn->ctx, from);
|
||||
}
|
||||
|
||||
int conn_tls_start(xmpp_conn_t *const conn)
|
||||
int conn_tls_start(xmpp_conn_t *conn)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -942,7 +1023,7 @@ int conn_tls_start(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
long xmpp_conn_get_flags(const xmpp_conn_t *const conn)
|
||||
long xmpp_conn_get_flags(const xmpp_conn_t *conn)
|
||||
{
|
||||
long flags;
|
||||
|
||||
@@ -977,7 +1058,7 @@ long xmpp_conn_get_flags(const xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_conn_set_flags(xmpp_conn_t *const conn, long flags)
|
||||
int xmpp_conn_set_flags(xmpp_conn_t *conn, long flags)
|
||||
{
|
||||
if (conn->state != XMPP_STATE_DISCONNECTED) {
|
||||
xmpp_error(conn->ctx, "conn",
|
||||
@@ -1012,7 +1093,7 @@ int xmpp_conn_set_flags(xmpp_conn_t *const conn, long flags)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
void xmpp_conn_disable_tls(xmpp_conn_t *const conn)
|
||||
void xmpp_conn_disable_tls(xmpp_conn_t *conn)
|
||||
{
|
||||
long flags = xmpp_conn_get_flags(conn);
|
||||
|
||||
@@ -1026,7 +1107,7 @@ void xmpp_conn_disable_tls(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_conn_is_secured(xmpp_conn_t *const conn)
|
||||
int xmpp_conn_is_secured(xmpp_conn_t *conn)
|
||||
{
|
||||
return conn->secured && !conn->tls_failed && conn->tls != NULL;
|
||||
}
|
||||
@@ -1036,7 +1117,7 @@ int xmpp_conn_is_secured(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_conn_is_connecting(xmpp_conn_t *const conn)
|
||||
int xmpp_conn_is_connecting(xmpp_conn_t *conn)
|
||||
{
|
||||
return conn->state == XMPP_STATE_CONNECTING;
|
||||
}
|
||||
@@ -1046,7 +1127,7 @@ int xmpp_conn_is_connecting(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_conn_is_connected(xmpp_conn_t *const conn)
|
||||
int xmpp_conn_is_connected(xmpp_conn_t *conn)
|
||||
{
|
||||
return conn->state == XMPP_STATE_CONNECTED;
|
||||
}
|
||||
@@ -1056,13 +1137,13 @@ int xmpp_conn_is_connected(xmpp_conn_t *const conn)
|
||||
*
|
||||
* @ingroup Connections
|
||||
*/
|
||||
int xmpp_conn_is_disconnected(xmpp_conn_t *const conn)
|
||||
int xmpp_conn_is_disconnected(xmpp_conn_t *conn)
|
||||
{
|
||||
return conn->state == XMPP_STATE_DISCONNECTED;
|
||||
}
|
||||
|
||||
/* timed handler for cleanup if normal disconnect procedure takes too long */
|
||||
static int _disconnect_cleanup(xmpp_conn_t *const conn, void *const userdata)
|
||||
static int _disconnect_cleanup(xmpp_conn_t *conn, void *userdata)
|
||||
{
|
||||
UNUSED(userdata);
|
||||
|
||||
@@ -1073,7 +1154,7 @@ static int _disconnect_cleanup(xmpp_conn_t *const conn, void *const userdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *_conn_build_stream_tag(xmpp_conn_t *const conn,
|
||||
static char *_conn_build_stream_tag(xmpp_conn_t *conn,
|
||||
char **attributes,
|
||||
size_t attributes_len)
|
||||
{
|
||||
@@ -1118,6 +1199,22 @@ static char *_conn_build_stream_tag(xmpp_conn_t *const conn,
|
||||
return tag;
|
||||
}
|
||||
|
||||
static int _conn_open_stream_with_attributes(xmpp_conn_t *conn,
|
||||
char **attributes,
|
||||
size_t attributes_len)
|
||||
{
|
||||
char *tag;
|
||||
|
||||
tag = _conn_build_stream_tag(conn, attributes, attributes_len);
|
||||
if (!tag)
|
||||
return XMPP_EMEM;
|
||||
|
||||
xmpp_send_raw_string(conn, "<?xml version=\"1.0\"?>%s", tag);
|
||||
xmpp_free(conn->ctx, tag);
|
||||
|
||||
return XMPP_EOK;
|
||||
}
|
||||
|
||||
static void _conn_attributes_new(xmpp_conn_t *conn,
|
||||
char **attrs,
|
||||
char ***attributes,
|
||||
@@ -1190,7 +1287,7 @@ static char *_get_stream_attribute(char **attrs, char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _handle_stream_start(char *name, char **attrs, void *const userdata)
|
||||
static void _handle_stream_start(char *name, char **attrs, void *userdata)
|
||||
{
|
||||
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
|
||||
char *id;
|
||||
@@ -1226,7 +1323,7 @@ static void _handle_stream_start(char *name, char **attrs, void *const userdata)
|
||||
}
|
||||
}
|
||||
|
||||
static void _handle_stream_end(char *name, void *const userdata)
|
||||
static void _handle_stream_end(char *name, void *userdata)
|
||||
{
|
||||
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
|
||||
|
||||
@@ -1237,7 +1334,7 @@ static void _handle_stream_end(char *name, void *const userdata)
|
||||
conn_disconnect_clean(conn);
|
||||
}
|
||||
|
||||
static void _handle_stream_stanza(xmpp_stanza_t *stanza, void *const userdata)
|
||||
static void _handle_stream_stanza(xmpp_stanza_t *stanza, void *userdata)
|
||||
{
|
||||
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
|
||||
char *buf;
|
||||
@@ -1251,7 +1348,7 @@ static void _handle_stream_stanza(xmpp_stanza_t *stanza, void *const userdata)
|
||||
handler_fire_stanza(conn, stanza);
|
||||
}
|
||||
|
||||
static unsigned short _conn_default_port(xmpp_conn_t *const conn,
|
||||
static unsigned short _conn_default_port(xmpp_conn_t *conn,
|
||||
xmpp_conn_type_t type)
|
||||
{
|
||||
switch (type) {
|
||||
@@ -1265,7 +1362,7 @@ static unsigned short _conn_default_port(xmpp_conn_t *const conn,
|
||||
};
|
||||
}
|
||||
|
||||
static void _conn_reset(xmpp_conn_t *const conn)
|
||||
static void _conn_reset(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_ctx_t *ctx = conn->ctx;
|
||||
xmpp_send_queue_t *sq, *tsq;
|
||||
@@ -1316,13 +1413,13 @@ static void _conn_reset(xmpp_conn_t *const conn)
|
||||
handler_system_delete_all(conn);
|
||||
}
|
||||
|
||||
static int _conn_connect(xmpp_conn_t *const conn,
|
||||
const char *const domain,
|
||||
const char *const host,
|
||||
static int _conn_connect(xmpp_conn_t *conn,
|
||||
const char *domain,
|
||||
const char *host,
|
||||
unsigned short port,
|
||||
xmpp_conn_type_t type,
|
||||
xmpp_conn_handler callback,
|
||||
void *const userdata)
|
||||
void *userdata)
|
||||
{
|
||||
xmpp_open_handler open_handler;
|
||||
|
||||
@@ -1352,10 +1449,9 @@ static int _conn_connect(xmpp_conn_t *const conn,
|
||||
conn->conn_handler = callback;
|
||||
conn->userdata = userdata;
|
||||
|
||||
open_handler = conn->is_raw
|
||||
? auth_handle_open_stub
|
||||
: type == XMPP_CLIENT ? auth_handle_open
|
||||
: auth_handle_component_open;
|
||||
open_handler = conn->is_raw ? auth_handle_open_stub
|
||||
: type == XMPP_CLIENT ? auth_handle_open
|
||||
: auth_handle_component_open;
|
||||
conn_prepare_reset(conn, open_handler);
|
||||
|
||||
/* FIXME: it could happen that the connect returns immediately as
|
||||
|
||||
13
src/crypto.c
13
src/crypto.c
@@ -244,15 +244,14 @@ static const char _base64_charmap[65] = {
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '='};
|
||||
|
||||
static size_t base64_encoded_len(const size_t len)
|
||||
static size_t base64_encoded_len(size_t len)
|
||||
{
|
||||
/* encoded steam is 4 bytes for every three, rounded up */
|
||||
return ((len + 2) / 3) << 2;
|
||||
}
|
||||
|
||||
static char *base64_encode(xmpp_ctx_t *ctx,
|
||||
const unsigned char *const buffer,
|
||||
const size_t len)
|
||||
static char *
|
||||
base64_encode(xmpp_ctx_t *ctx, const unsigned char *buffer, size_t len)
|
||||
{
|
||||
size_t clen;
|
||||
char *cbuf, *c;
|
||||
@@ -304,7 +303,7 @@ static char *base64_encode(xmpp_ctx_t *ctx,
|
||||
return cbuf;
|
||||
}
|
||||
|
||||
static size_t base64_decoded_len(const char *const buffer, const size_t len)
|
||||
static size_t base64_decoded_len(const char *buffer, size_t len)
|
||||
{
|
||||
size_t nudge = 0;
|
||||
unsigned char c;
|
||||
@@ -331,8 +330,8 @@ static size_t base64_decoded_len(const char *const buffer, const size_t len)
|
||||
}
|
||||
|
||||
static void base64_decode(xmpp_ctx_t *ctx,
|
||||
const char *const buffer,
|
||||
const size_t len,
|
||||
const char *buffer,
|
||||
size_t len,
|
||||
unsigned char **out,
|
||||
size_t *outlen)
|
||||
{
|
||||
|
||||
58
src/ctx.c
58
src/ctx.c
@@ -122,19 +122,19 @@ int xmpp_version_check(int major, int minor)
|
||||
/* Wrap stdlib routines malloc, free, and realloc for default memory
|
||||
* management.
|
||||
*/
|
||||
static void *_malloc(const size_t size, void *const userdata)
|
||||
static void *_malloc(size_t size, void *userdata)
|
||||
{
|
||||
UNUSED(userdata);
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void _free(void *p, void *const userdata)
|
||||
static void _free(void *p, void *userdata)
|
||||
{
|
||||
UNUSED(userdata);
|
||||
free(p);
|
||||
}
|
||||
|
||||
static void *_realloc(void *p, const size_t size, void *const userdata)
|
||||
static void *_realloc(void *p, size_t size, void *userdata)
|
||||
{
|
||||
UNUSED(userdata);
|
||||
return realloc(p, size);
|
||||
@@ -146,8 +146,7 @@ static xmpp_mem_t xmpp_default_mem = {
|
||||
_free, _realloc, NULL};
|
||||
|
||||
/* log levels and names */
|
||||
static const char *const _xmpp_log_level_name[4] = {"DEBUG", "INFO", "WARN",
|
||||
"ERROR"};
|
||||
static const char *_xmpp_log_level_name[4] = {"DEBUG", "INFO", "WARN", "ERROR"};
|
||||
static const xmpp_log_level_t _xmpp_default_logger_levels[] = {
|
||||
XMPP_LEVEL_DEBUG, XMPP_LEVEL_INFO, XMPP_LEVEL_WARN, XMPP_LEVEL_ERROR};
|
||||
|
||||
@@ -160,10 +159,10 @@ static const xmpp_log_level_t _xmpp_default_logger_levels[] = {
|
||||
* @param area the area the log message is for
|
||||
* @param msg the log message
|
||||
*/
|
||||
static void xmpp_default_logger(void *const userdata,
|
||||
const xmpp_log_level_t level,
|
||||
const char *const area,
|
||||
const char *const msg)
|
||||
static void xmpp_default_logger(void *userdata,
|
||||
xmpp_log_level_t level,
|
||||
const char *area,
|
||||
const char *msg)
|
||||
{
|
||||
xmpp_log_level_t filter_level = *(xmpp_log_level_t *)userdata;
|
||||
if (level >= filter_level)
|
||||
@@ -212,7 +211,7 @@ static xmpp_log_t xmpp_default_log = {NULL, NULL};
|
||||
*
|
||||
* @return a pointer to the allocated memory or NULL on an error
|
||||
*/
|
||||
void *xmpp_alloc(const xmpp_ctx_t *const ctx, const size_t size)
|
||||
void *xmpp_alloc(const xmpp_ctx_t *ctx, size_t size)
|
||||
{
|
||||
return ctx->mem->alloc(size, ctx->mem->userdata);
|
||||
}
|
||||
@@ -223,7 +222,7 @@ void *xmpp_alloc(const xmpp_ctx_t *const ctx, const size_t size)
|
||||
* @param ctx a Strophe context object
|
||||
* @param p a pointer referencing memory to be freed
|
||||
*/
|
||||
void xmpp_free(const xmpp_ctx_t *const ctx, void *p)
|
||||
void xmpp_free(const xmpp_ctx_t *ctx, void *p)
|
||||
{
|
||||
ctx->mem->free(p, ctx->mem->userdata);
|
||||
}
|
||||
@@ -237,7 +236,7 @@ void xmpp_free(const xmpp_ctx_t *const ctx, void *p)
|
||||
*
|
||||
* @return a pointer to the reallocated memory or NULL on an error
|
||||
*/
|
||||
void *xmpp_realloc(const xmpp_ctx_t *const ctx, void *p, const size_t size)
|
||||
void *xmpp_realloc(const xmpp_ctx_t *ctx, void *p, size_t size)
|
||||
{
|
||||
return ctx->mem->realloc(p, size, ctx->mem->userdata);
|
||||
}
|
||||
@@ -255,10 +254,10 @@ void *xmpp_realloc(const xmpp_ctx_t *const ctx, void *p, const size_t size)
|
||||
* @param fmt a printf-style format string for the message
|
||||
* @param ap variable argument list supplied for the format string
|
||||
*/
|
||||
void xmpp_log(const xmpp_ctx_t *const ctx,
|
||||
const xmpp_log_level_t level,
|
||||
const char *const area,
|
||||
const char *const fmt,
|
||||
void xmpp_log(const xmpp_ctx_t *ctx,
|
||||
xmpp_log_level_t level,
|
||||
const char *area,
|
||||
const char *fmt,
|
||||
va_list ap)
|
||||
{
|
||||
int oldret, ret;
|
||||
@@ -306,10 +305,7 @@ void xmpp_log(const xmpp_ctx_t *const ctx,
|
||||
* @param fmt a printf-style format string followed by a variable list of
|
||||
* arguments to format
|
||||
*/
|
||||
void xmpp_error(const xmpp_ctx_t *const ctx,
|
||||
const char *const area,
|
||||
const char *const fmt,
|
||||
...)
|
||||
void xmpp_error(const xmpp_ctx_t *ctx, const char *area, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -328,10 +324,7 @@ void xmpp_error(const xmpp_ctx_t *const ctx,
|
||||
* @param fmt a printf-style format string followed by a variable list of
|
||||
* arguments to format
|
||||
*/
|
||||
void xmpp_warn(const xmpp_ctx_t *const ctx,
|
||||
const char *const area,
|
||||
const char *const fmt,
|
||||
...)
|
||||
void xmpp_warn(const xmpp_ctx_t *ctx, const char *area, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -350,10 +343,7 @@ void xmpp_warn(const xmpp_ctx_t *const ctx,
|
||||
* @param fmt a printf-style format string followed by a variable list of
|
||||
* arguments to format
|
||||
*/
|
||||
void xmpp_info(const xmpp_ctx_t *const ctx,
|
||||
const char *const area,
|
||||
const char *const fmt,
|
||||
...)
|
||||
void xmpp_info(const xmpp_ctx_t *ctx, const char *area, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -372,10 +362,7 @@ void xmpp_info(const xmpp_ctx_t *const ctx,
|
||||
* @param fmt a printf-style format string followed by a variable list of
|
||||
* arguments to format
|
||||
*/
|
||||
void xmpp_debug(const xmpp_ctx_t *const ctx,
|
||||
const char *const area,
|
||||
const char *const fmt,
|
||||
...)
|
||||
void xmpp_debug(const xmpp_ctx_t *ctx, const char *area, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -398,8 +385,7 @@ void xmpp_debug(const xmpp_ctx_t *const ctx,
|
||||
*
|
||||
* @ingroup Context
|
||||
*/
|
||||
xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t *const mem,
|
||||
const xmpp_log_t *const log)
|
||||
xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t *mem, const xmpp_log_t *log)
|
||||
{
|
||||
xmpp_ctx_t *ctx = NULL;
|
||||
|
||||
@@ -439,7 +425,7 @@ xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t *const mem,
|
||||
*
|
||||
* @ingroup Context
|
||||
*/
|
||||
void xmpp_ctx_free(xmpp_ctx_t *const ctx)
|
||||
void xmpp_ctx_free(xmpp_ctx_t *ctx)
|
||||
{
|
||||
/* mem and log are owned by their suppliers */
|
||||
xmpp_rand_free(ctx, ctx->rand);
|
||||
@@ -453,7 +439,7 @@ void xmpp_ctx_free(xmpp_ctx_t *const ctx)
|
||||
*
|
||||
* @ingroup Context
|
||||
*/
|
||||
void xmpp_ctx_set_timeout(xmpp_ctx_t *const ctx, const unsigned long timeout)
|
||||
void xmpp_ctx_set_timeout(xmpp_ctx_t *ctx, unsigned long timeout)
|
||||
{
|
||||
ctx->timeout = timeout;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
*
|
||||
* @ingroup EventLoop
|
||||
*/
|
||||
void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
|
||||
void xmpp_run_once(xmpp_ctx_t *ctx, unsigned long timeout)
|
||||
{
|
||||
xmpp_connlist_t *connitem;
|
||||
xmpp_conn_t *conn;
|
||||
|
||||
@@ -53,7 +53,7 @@ static void _handler_item_remove(xmpp_handlist_t **head, xmpp_handlist_t *item)
|
||||
* @param conn a Strophe connection object
|
||||
* @param stanza a Strophe stanza object
|
||||
*/
|
||||
void handler_fire_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
|
||||
void handler_fire_stanza(xmpp_conn_t *conn, xmpp_stanza_t *stanza)
|
||||
{
|
||||
xmpp_handlist_t *item, *next, *head, *head_old;
|
||||
const char *id, *ns, *name, *type;
|
||||
@@ -144,7 +144,7 @@ void handler_fire_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @return the time in milliseconds until the next handler will be ready
|
||||
*/
|
||||
uint64_t handler_fire_timed(xmpp_ctx_t *const ctx)
|
||||
uint64_t handler_fire_timed(xmpp_ctx_t *ctx)
|
||||
{
|
||||
xmpp_connlist_t *connitem;
|
||||
xmpp_handlist_t *item, *next;
|
||||
@@ -253,9 +253,9 @@ void handler_reset_timed(xmpp_conn_t *conn, int user_only)
|
||||
static void _timed_handler_add(xmpp_ctx_t *ctx,
|
||||
xmpp_handlist_t **handlers_list,
|
||||
xmpp_void_handler handler,
|
||||
const unsigned long period,
|
||||
void *const userdata,
|
||||
const int user_handler)
|
||||
unsigned long period,
|
||||
void *userdata,
|
||||
int user_handler)
|
||||
{
|
||||
xmpp_handlist_t *item;
|
||||
|
||||
@@ -311,16 +311,15 @@ static void _timed_handler_delete(xmpp_ctx_t *ctx,
|
||||
*
|
||||
* @ingroup Handlers
|
||||
*/
|
||||
void xmpp_timed_handler_delete(xmpp_conn_t *const conn,
|
||||
xmpp_timed_handler handler)
|
||||
void xmpp_timed_handler_delete(xmpp_conn_t *conn, xmpp_timed_handler handler)
|
||||
{
|
||||
_timed_handler_delete(conn->ctx, &conn->timed_handlers, handler);
|
||||
}
|
||||
|
||||
static void _id_handler_add(xmpp_conn_t *const conn,
|
||||
static void _id_handler_add(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const id,
|
||||
void *const userdata,
|
||||
const char *id,
|
||||
void *userdata,
|
||||
int user_handler)
|
||||
{
|
||||
xmpp_handlist_t *item, *tail;
|
||||
@@ -373,9 +372,9 @@ static void _id_handler_add(xmpp_conn_t *const conn,
|
||||
*
|
||||
* @ingroup Handlers
|
||||
*/
|
||||
void xmpp_id_handler_delete(xmpp_conn_t *const conn,
|
||||
void xmpp_id_handler_delete(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const id)
|
||||
const char *id)
|
||||
{
|
||||
xmpp_handlist_t *item, *prev, *next;
|
||||
|
||||
@@ -406,12 +405,12 @@ void xmpp_id_handler_delete(xmpp_conn_t *const conn,
|
||||
}
|
||||
|
||||
/* add a stanza handler */
|
||||
static void _handler_add(xmpp_conn_t *const conn,
|
||||
static void _handler_add(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const ns,
|
||||
const char *const name,
|
||||
const char *const type,
|
||||
void *const userdata,
|
||||
const char *ns,
|
||||
const char *name,
|
||||
const char *type,
|
||||
void *userdata,
|
||||
int user_handler)
|
||||
{
|
||||
xmpp_handlist_t *item, *tail;
|
||||
@@ -489,7 +488,7 @@ static void _handler_add(xmpp_conn_t *const conn,
|
||||
*
|
||||
* @ingroup Handlers
|
||||
*/
|
||||
void xmpp_handler_delete(xmpp_conn_t *const conn, xmpp_handler handler)
|
||||
void xmpp_handler_delete(xmpp_conn_t *conn, xmpp_handler handler)
|
||||
{
|
||||
xmpp_handlist_t *prev, *item;
|
||||
|
||||
@@ -536,10 +535,10 @@ void xmpp_handler_delete(xmpp_conn_t *const conn, xmpp_handler handler)
|
||||
*
|
||||
* @ingroup Handlers
|
||||
*/
|
||||
void xmpp_timed_handler_add(xmpp_conn_t *const conn,
|
||||
void xmpp_timed_handler_add(xmpp_conn_t *conn,
|
||||
xmpp_timed_handler handler,
|
||||
const unsigned long period,
|
||||
void *const userdata)
|
||||
unsigned long period,
|
||||
void *userdata)
|
||||
{
|
||||
_timed_handler_add(conn->ctx, &conn->timed_handlers, handler, period,
|
||||
userdata, 1);
|
||||
@@ -554,10 +553,10 @@ void xmpp_timed_handler_add(xmpp_conn_t *const conn,
|
||||
* @param period the time in milliseconds between firings
|
||||
* @param userdata an opaque data pointer that will be passed to the handler
|
||||
*/
|
||||
void handler_add_timed(xmpp_conn_t *const conn,
|
||||
void handler_add_timed(xmpp_conn_t *conn,
|
||||
xmpp_timed_handler handler,
|
||||
const unsigned long period,
|
||||
void *const userdata)
|
||||
unsigned long period,
|
||||
void *userdata)
|
||||
{
|
||||
_timed_handler_add(conn->ctx, &conn->timed_handlers, handler, period,
|
||||
userdata, 0);
|
||||
@@ -579,10 +578,10 @@ void handler_add_timed(xmpp_conn_t *const conn,
|
||||
*
|
||||
* @ingroup Handlers
|
||||
*/
|
||||
void xmpp_id_handler_add(xmpp_conn_t *const conn,
|
||||
void xmpp_id_handler_add(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const id,
|
||||
void *const userdata)
|
||||
const char *id,
|
||||
void *userdata)
|
||||
{
|
||||
_id_handler_add(conn, handler, id, userdata, 1);
|
||||
}
|
||||
@@ -596,10 +595,10 @@ void xmpp_id_handler_add(xmpp_conn_t *const conn,
|
||||
* @param id a string with the id
|
||||
* @param userdata an opaque data pointer that will be passed to the handler
|
||||
*/
|
||||
void handler_add_id(xmpp_conn_t *const conn,
|
||||
void handler_add_id(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const id,
|
||||
void *const userdata)
|
||||
const char *id,
|
||||
void *userdata)
|
||||
{
|
||||
_id_handler_add(conn, handler, id, userdata, 0);
|
||||
}
|
||||
@@ -626,12 +625,12 @@ void handler_add_id(xmpp_conn_t *const conn,
|
||||
*
|
||||
* @ingroup Handlers
|
||||
*/
|
||||
void xmpp_handler_add(xmpp_conn_t *const conn,
|
||||
void xmpp_handler_add(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const ns,
|
||||
const char *const name,
|
||||
const char *const type,
|
||||
void *const userdata)
|
||||
const char *ns,
|
||||
const char *name,
|
||||
const char *type,
|
||||
void *userdata)
|
||||
{
|
||||
_handler_add(conn, handler, ns, name, type, userdata, 1);
|
||||
}
|
||||
@@ -647,12 +646,12 @@ void xmpp_handler_add(xmpp_conn_t *const conn,
|
||||
* @param type a string with the 'type' attribute value to match
|
||||
* @param userdata an opaque data pointer that will be passed to the handler
|
||||
*/
|
||||
void handler_add(xmpp_conn_t *const conn,
|
||||
void handler_add(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const ns,
|
||||
const char *const name,
|
||||
const char *const type,
|
||||
void *const userdata)
|
||||
const char *ns,
|
||||
const char *name,
|
||||
const char *type,
|
||||
void *userdata)
|
||||
{
|
||||
_handler_add(conn, handler, ns, name, type, userdata, 0);
|
||||
}
|
||||
@@ -762,10 +761,10 @@ void handler_system_delete_all(xmpp_conn_t *conn)
|
||||
*
|
||||
* @ingroup Handlers
|
||||
*/
|
||||
void xmpp_global_timed_handler_add(xmpp_ctx_t *const ctx,
|
||||
void xmpp_global_timed_handler_add(xmpp_ctx_t *ctx,
|
||||
xmpp_global_timed_handler handler,
|
||||
const unsigned long period,
|
||||
void *const userdata)
|
||||
unsigned long period,
|
||||
void *userdata)
|
||||
{
|
||||
_timed_handler_add(ctx, &ctx->timed_handlers, handler, period, userdata, 1);
|
||||
}
|
||||
@@ -777,7 +776,7 @@ void xmpp_global_timed_handler_add(xmpp_ctx_t *const ctx,
|
||||
*
|
||||
* @ingroup Handlers
|
||||
*/
|
||||
void xmpp_global_timed_handler_delete(xmpp_ctx_t *const ctx,
|
||||
void xmpp_global_timed_handler_delete(xmpp_ctx_t *ctx,
|
||||
xmpp_global_timed_handler handler)
|
||||
{
|
||||
_timed_handler_delete(ctx, &ctx->timed_handlers, handler);
|
||||
|
||||
@@ -46,8 +46,7 @@ struct _hash_iterator_t {
|
||||
};
|
||||
|
||||
/** allocate and initialize a new hash table */
|
||||
hash_t *
|
||||
hash_new(xmpp_ctx_t *const ctx, const int size, hash_free_func free_func)
|
||||
hash_t *hash_new(xmpp_ctx_t *ctx, int size, hash_free_func free_func)
|
||||
{
|
||||
hash_t *result = NULL;
|
||||
|
||||
@@ -72,14 +71,14 @@ hash_new(xmpp_ctx_t *const ctx, const int size, hash_free_func free_func)
|
||||
}
|
||||
|
||||
/** obtain a new reference to an existing hash table */
|
||||
hash_t *hash_clone(hash_t *const table)
|
||||
hash_t *hash_clone(hash_t *table)
|
||||
{
|
||||
table->ref++;
|
||||
return table;
|
||||
}
|
||||
|
||||
/** release a hash table that is no longer needed */
|
||||
void hash_release(hash_t *const table)
|
||||
void hash_release(hash_t *table)
|
||||
{
|
||||
xmpp_ctx_t *ctx = table->ctx;
|
||||
hashentry_t *entry, *next;
|
||||
@@ -143,7 +142,7 @@ hashentry_t *_hash_entry_find(hash_t *table, const char *key)
|
||||
* each key can appear only once; the value of any
|
||||
* identical key will be replaced
|
||||
*/
|
||||
int hash_add(hash_t *table, const char *const key, void *data)
|
||||
int hash_add(hash_t *table, const char *key, void *data)
|
||||
{
|
||||
xmpp_ctx_t *ctx = table->ctx;
|
||||
hashentry_t *entry = NULL;
|
||||
|
||||
11
src/hash.h
11
src/hash.h
@@ -18,23 +18,22 @@
|
||||
|
||||
typedef struct _hash_t hash_t;
|
||||
|
||||
typedef void (*hash_free_func)(const xmpp_ctx_t *const ctx, void *p);
|
||||
typedef void (*hash_free_func)(const xmpp_ctx_t *ctx, void *p);
|
||||
|
||||
/** allocate and initialize a new hash table */
|
||||
hash_t *
|
||||
hash_new(xmpp_ctx_t *const ctx, const int size, hash_free_func free_func);
|
||||
hash_t *hash_new(xmpp_ctx_t *ctx, int size, hash_free_func free_func);
|
||||
|
||||
/** allocate a new reference to an existing hash table */
|
||||
hash_t *hash_clone(hash_t *const table);
|
||||
hash_t *hash_clone(hash_t *table);
|
||||
|
||||
/** release a hash table when no longer needed */
|
||||
void hash_release(hash_t *const table);
|
||||
void hash_release(hash_t *table);
|
||||
|
||||
/** add a key, value pair to a hash table.
|
||||
* each key can appear only once; the value of any
|
||||
* identical key will be replaced
|
||||
*/
|
||||
int hash_add(hash_t *table, const char *const key, void *data);
|
||||
int hash_add(hash_t *table, const char *key, void *data);
|
||||
|
||||
/** look up a key in a hash table */
|
||||
void *hash_get(hash_t *table, const char *key);
|
||||
|
||||
@@ -20,12 +20,9 @@
|
||||
|
||||
typedef struct _parser_t parser_t;
|
||||
|
||||
typedef void (*parser_start_callback)(char *name,
|
||||
char **attrs,
|
||||
void *const userdata);
|
||||
typedef void (*parser_end_callback)(char *name, void *const userdata);
|
||||
typedef void (*parser_stanza_callback)(xmpp_stanza_t *stanza,
|
||||
void *const userdata);
|
||||
typedef void (*parser_start_callback)(char *name, char **attrs, void *userdata);
|
||||
typedef void (*parser_end_callback)(char *name, void *userdata);
|
||||
typedef void (*parser_stanza_callback)(xmpp_stanza_t *stanza, void *userdata);
|
||||
|
||||
parser_t *parser_new(xmpp_ctx_t *ctx,
|
||||
parser_start_callback startcb,
|
||||
|
||||
@@ -65,7 +65,7 @@ char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password)
|
||||
/** helpers for digest auth */
|
||||
|
||||
/* create a new, null-terminated string from a substring */
|
||||
static char *_make_string(xmpp_ctx_t *ctx, const char *s, const unsigned len)
|
||||
static char *_make_string(xmpp_ctx_t *ctx, const char *s, unsigned len)
|
||||
{
|
||||
char *result;
|
||||
|
||||
|
||||
@@ -206,9 +206,7 @@ void crypto_SHA1_Init(SHA1_CTX *context)
|
||||
}
|
||||
|
||||
/* Run your data through this. */
|
||||
void crypto_SHA1_Update(SHA1_CTX *context,
|
||||
const uint8_t *data,
|
||||
const size_t len)
|
||||
void crypto_SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len)
|
||||
{
|
||||
size_t i, j;
|
||||
|
||||
|
||||
@@ -24,9 +24,7 @@ typedef struct {
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
void crypto_SHA1_Init(SHA1_CTX *context);
|
||||
void crypto_SHA1_Update(SHA1_CTX *context,
|
||||
const uint8_t *data,
|
||||
const size_t len);
|
||||
void crypto_SHA1_Update(SHA1_CTX *context, const uint8_t *data, size_t len);
|
||||
void crypto_SHA1_Final(SHA1_CTX *context, uint8_t *digest);
|
||||
void crypto_SHA1(const uint8_t *data, size_t len, uint8_t *digest);
|
||||
|
||||
|
||||
18
src/sock.c
18
src/sock.c
@@ -69,7 +69,7 @@ static int _in_progress(int error)
|
||||
#endif
|
||||
}
|
||||
|
||||
sock_t sock_connect(const char *const host, const unsigned short port)
|
||||
sock_t sock_connect(const char *host, unsigned short port)
|
||||
{
|
||||
sock_t sock;
|
||||
char service[6];
|
||||
@@ -109,7 +109,7 @@ sock_t sock_connect(const char *const host, const unsigned short port)
|
||||
return sock;
|
||||
}
|
||||
|
||||
int sock_set_keepalive(const sock_t sock, int timeout, int interval)
|
||||
int sock_set_keepalive(sock_t sock, int timeout, int interval)
|
||||
{
|
||||
int ret;
|
||||
int optval = (timeout && interval) ? 1 : 0;
|
||||
@@ -154,7 +154,7 @@ int sock_set_keepalive(const sock_t sock, int timeout, int interval)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sock_close(const sock_t sock)
|
||||
int sock_close(sock_t sock)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return closesocket(sock);
|
||||
@@ -180,27 +180,27 @@ static int _sock_set_blocking_mode(sock_t sock, int blocking)
|
||||
#endif
|
||||
}
|
||||
|
||||
int sock_set_blocking(const sock_t sock)
|
||||
int sock_set_blocking(sock_t sock)
|
||||
{
|
||||
return _sock_set_blocking_mode(sock, 1);
|
||||
}
|
||||
|
||||
int sock_set_nonblocking(const sock_t sock)
|
||||
int sock_set_nonblocking(sock_t sock)
|
||||
{
|
||||
return _sock_set_blocking_mode(sock, 0);
|
||||
}
|
||||
|
||||
int sock_read(const sock_t sock, void *const buff, const size_t len)
|
||||
int sock_read(sock_t sock, void *buff, size_t len)
|
||||
{
|
||||
return recv(sock, buff, len, 0);
|
||||
}
|
||||
|
||||
int sock_write(const sock_t sock, const void *const buff, const size_t len)
|
||||
int sock_write(sock_t sock, const void *buff, size_t len)
|
||||
{
|
||||
return send(sock, buff, len, 0);
|
||||
}
|
||||
|
||||
int sock_is_recoverable(const int error)
|
||||
int sock_is_recoverable(int error)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (error == WSAEINTR || error == WSAEWOULDBLOCK ||
|
||||
@@ -210,7 +210,7 @@ int sock_is_recoverable(const int error)
|
||||
#endif
|
||||
}
|
||||
|
||||
int sock_connect_error(const sock_t sock)
|
||||
int sock_connect_error(sock_t sock)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr *sa = (struct sockaddr *)&ss;
|
||||
|
||||
18
src/sock.h
18
src/sock.h
@@ -30,16 +30,16 @@ void sock_shutdown(void);
|
||||
|
||||
int sock_error(void);
|
||||
|
||||
sock_t sock_connect(const char *const host, const unsigned short port);
|
||||
int sock_close(const sock_t sock);
|
||||
sock_t sock_connect(const char *host, unsigned short port);
|
||||
int sock_close(sock_t sock);
|
||||
|
||||
int sock_set_blocking(const sock_t sock);
|
||||
int sock_set_nonblocking(const sock_t sock);
|
||||
int sock_read(const sock_t sock, void *const buff, const size_t len);
|
||||
int sock_write(const sock_t sock, const void *const buff, const size_t len);
|
||||
int sock_is_recoverable(const int error);
|
||||
int sock_set_blocking(sock_t sock);
|
||||
int sock_set_nonblocking(sock_t sock);
|
||||
int sock_read(sock_t sock, void *buff, size_t len);
|
||||
int sock_write(sock_t sock, const void *buff, size_t len);
|
||||
int sock_is_recoverable(int error);
|
||||
/* checks for an error after connect, return 0 if connect successful */
|
||||
int sock_connect_error(const sock_t sock);
|
||||
int sock_set_keepalive(const sock_t sock, int timeout, int interval);
|
||||
int sock_connect_error(sock_t sock);
|
||||
int sock_set_keepalive(sock_t sock, int timeout, int interval);
|
||||
|
||||
#endif /* __LIBSTROPHE_SOCK_H__ */
|
||||
|
||||
135
src/stanza.c
135
src/stanza.c
@@ -64,7 +64,7 @@ xmpp_stanza_t *xmpp_stanza_new(xmpp_ctx_t *ctx)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t *const stanza)
|
||||
xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t *stanza)
|
||||
{
|
||||
stanza->ref++;
|
||||
|
||||
@@ -74,8 +74,7 @@ xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t *const stanza)
|
||||
/*
|
||||
* Copy the attributes of stanza src into stanza dst. Return -1 on error.
|
||||
*/
|
||||
static int _stanza_copy_attributes(xmpp_stanza_t *dst,
|
||||
const xmpp_stanza_t *const src)
|
||||
static int _stanza_copy_attributes(xmpp_stanza_t *dst, const xmpp_stanza_t *src)
|
||||
{
|
||||
hash_iterator_t *iter;
|
||||
const char *key;
|
||||
@@ -114,7 +113,7 @@ static int _stanza_copy_attributes(xmpp_stanza_t *dst,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t *const stanza)
|
||||
xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t *stanza)
|
||||
{
|
||||
xmpp_stanza_t *copy, *child, *copychild, *tail;
|
||||
|
||||
@@ -169,7 +168,7 @@ copy_error:
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_release(xmpp_stanza_t *const stanza)
|
||||
int xmpp_stanza_release(xmpp_stanza_t *stanza)
|
||||
{
|
||||
int released = 0;
|
||||
xmpp_stanza_t *child, *tchild;
|
||||
@@ -205,7 +204,7 @@ int xmpp_stanza_release(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_ctx_t *xmpp_stanza_get_context(const xmpp_stanza_t *const stanza)
|
||||
xmpp_ctx_t *xmpp_stanza_get_context(const xmpp_stanza_t *stanza)
|
||||
{
|
||||
return stanza->ctx;
|
||||
}
|
||||
@@ -218,7 +217,7 @@ xmpp_ctx_t *xmpp_stanza_get_context(const xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_is_text(xmpp_stanza_t *const stanza)
|
||||
int xmpp_stanza_is_text(xmpp_stanza_t *stanza)
|
||||
{
|
||||
return (stanza && stanza->type == XMPP_STANZA_TEXT);
|
||||
}
|
||||
@@ -231,7 +230,7 @@ int xmpp_stanza_is_text(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_is_tag(xmpp_stanza_t *const stanza)
|
||||
int xmpp_stanza_is_tag(xmpp_stanza_t *stanza)
|
||||
{
|
||||
return (stanza && stanza->type == XMPP_STANZA_TAG);
|
||||
}
|
||||
@@ -242,7 +241,7 @@ int xmpp_stanza_is_tag(xmpp_stanza_t *const stanza)
|
||||
* On failure, returns NULL.
|
||||
*/
|
||||
|
||||
static char *_escape_xml(xmpp_ctx_t *const ctx, char *text)
|
||||
static char *_escape_xml(xmpp_ctx_t *ctx, char *text)
|
||||
{
|
||||
size_t len = 0;
|
||||
char *src;
|
||||
@@ -295,11 +294,8 @@ static char *_escape_xml(xmpp_ctx_t *const ctx, char *text)
|
||||
}
|
||||
|
||||
/* small helper function */
|
||||
static void _render_update(int *written,
|
||||
const int length,
|
||||
const int lastwrite,
|
||||
size_t *left,
|
||||
char **ptr)
|
||||
static void _render_update(
|
||||
int *written, int length, int lastwrite, size_t *left, char **ptr)
|
||||
{
|
||||
*written += lastwrite;
|
||||
|
||||
@@ -317,9 +313,8 @@ static void _render_update(int *written,
|
||||
* return values < 0 indicate some error occurred,
|
||||
* and return values > buflen indicate buffer was not large enough
|
||||
*/
|
||||
static int _render_stanza_recursive(xmpp_stanza_t *stanza,
|
||||
char *const buf,
|
||||
size_t const buflen)
|
||||
static int
|
||||
_render_stanza_recursive(xmpp_stanza_t *stanza, char *buf, size_t buflen)
|
||||
{
|
||||
char *ptr = buf;
|
||||
size_t left = buflen;
|
||||
@@ -444,9 +439,7 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_to_text(xmpp_stanza_t *stanza,
|
||||
char **const buf,
|
||||
size_t *const buflen)
|
||||
int xmpp_stanza_to_text(xmpp_stanza_t *stanza, char **buf, size_t *buflen)
|
||||
{
|
||||
char *buffer, *tmp;
|
||||
size_t length;
|
||||
@@ -507,7 +500,7 @@ int xmpp_stanza_to_text(xmpp_stanza_t *stanza,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_set_name(xmpp_stanza_t *stanza, const char *const name)
|
||||
int xmpp_stanza_set_name(xmpp_stanza_t *stanza, const char *name)
|
||||
{
|
||||
if (stanza->type == XMPP_STANZA_TEXT)
|
||||
return XMPP_EINVOP;
|
||||
@@ -531,7 +524,7 @@ int xmpp_stanza_set_name(xmpp_stanza_t *stanza, const char *const name)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
const char *xmpp_stanza_get_name(xmpp_stanza_t *const stanza)
|
||||
const char *xmpp_stanza_get_name(xmpp_stanza_t *stanza)
|
||||
{
|
||||
if (stanza->type == XMPP_STANZA_TEXT)
|
||||
return NULL;
|
||||
@@ -546,7 +539,7 @@ const char *xmpp_stanza_get_name(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_get_attribute_count(xmpp_stanza_t *const stanza)
|
||||
int xmpp_stanza_get_attribute_count(xmpp_stanza_t *stanza)
|
||||
{
|
||||
if (stanza->attributes == NULL) {
|
||||
return 0;
|
||||
@@ -569,7 +562,7 @@ int xmpp_stanza_get_attribute_count(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_get_attributes(xmpp_stanza_t *const stanza,
|
||||
int xmpp_stanza_get_attributes(xmpp_stanza_t *stanza,
|
||||
const char **attr,
|
||||
int attrlen)
|
||||
{
|
||||
@@ -611,9 +604,9 @@ int xmpp_stanza_get_attributes(xmpp_stanza_t *const stanza,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_set_attribute(xmpp_stanza_t *const stanza,
|
||||
const char *const key,
|
||||
const char *const value)
|
||||
int xmpp_stanza_set_attribute(xmpp_stanza_t *stanza,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
char *val;
|
||||
int rc;
|
||||
@@ -652,7 +645,7 @@ int xmpp_stanza_set_attribute(xmpp_stanza_t *const stanza,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_set_ns(xmpp_stanza_t *const stanza, const char *const ns)
|
||||
int xmpp_stanza_set_ns(xmpp_stanza_t *stanza, const char *ns)
|
||||
{
|
||||
return xmpp_stanza_set_attribute(stanza, "xmlns", ns);
|
||||
}
|
||||
@@ -727,7 +720,7 @@ int xmpp_stanza_add_child(xmpp_stanza_t *stanza, xmpp_stanza_t *child)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_set_text(xmpp_stanza_t *stanza, const char *const text)
|
||||
int xmpp_stanza_set_text(xmpp_stanza_t *stanza, const char *text)
|
||||
{
|
||||
if (stanza->type == XMPP_STANZA_TAG)
|
||||
return XMPP_EINVOP;
|
||||
@@ -756,8 +749,8 @@ int xmpp_stanza_set_text(xmpp_stanza_t *stanza, const char *const text)
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_set_text_with_size(xmpp_stanza_t *stanza,
|
||||
const char *const text,
|
||||
const size_t size)
|
||||
const char *text,
|
||||
size_t size)
|
||||
{
|
||||
if (stanza->type == XMPP_STANZA_TAG)
|
||||
return XMPP_EINVOP;
|
||||
@@ -786,7 +779,7 @@ int xmpp_stanza_set_text_with_size(xmpp_stanza_t *stanza,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
const char *xmpp_stanza_get_id(xmpp_stanza_t *const stanza)
|
||||
const char *xmpp_stanza_get_id(xmpp_stanza_t *stanza)
|
||||
{
|
||||
return xmpp_stanza_get_attribute(stanza, "id");
|
||||
}
|
||||
@@ -801,7 +794,7 @@ const char *xmpp_stanza_get_id(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
const char *xmpp_stanza_get_ns(xmpp_stanza_t *const stanza)
|
||||
const char *xmpp_stanza_get_ns(xmpp_stanza_t *stanza)
|
||||
{
|
||||
return xmpp_stanza_get_attribute(stanza, "xmlns");
|
||||
}
|
||||
@@ -816,7 +809,7 @@ const char *xmpp_stanza_get_ns(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
const char *xmpp_stanza_get_type(xmpp_stanza_t *const stanza)
|
||||
const char *xmpp_stanza_get_type(xmpp_stanza_t *stanza)
|
||||
{
|
||||
return xmpp_stanza_get_attribute(stanza, "type");
|
||||
}
|
||||
@@ -831,7 +824,7 @@ const char *xmpp_stanza_get_type(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
const char *xmpp_stanza_get_to(xmpp_stanza_t *const stanza)
|
||||
const char *xmpp_stanza_get_to(xmpp_stanza_t *stanza)
|
||||
{
|
||||
return xmpp_stanza_get_attribute(stanza, "to");
|
||||
}
|
||||
@@ -846,7 +839,7 @@ const char *xmpp_stanza_get_to(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
const char *xmpp_stanza_get_from(xmpp_stanza_t *const stanza)
|
||||
const char *xmpp_stanza_get_from(xmpp_stanza_t *stanza)
|
||||
{
|
||||
return xmpp_stanza_get_attribute(stanza, "from");
|
||||
}
|
||||
@@ -862,8 +855,8 @@ const char *xmpp_stanza_get_from(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t *const stanza,
|
||||
const char *const name)
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t *stanza,
|
||||
const char *name)
|
||||
{
|
||||
xmpp_stanza_t *child;
|
||||
|
||||
@@ -888,8 +881,8 @@ xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t *const stanza,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t *const stanza,
|
||||
const char *const ns)
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t *stanza,
|
||||
const char *ns)
|
||||
{
|
||||
xmpp_stanza_t *child;
|
||||
const char *child_ns;
|
||||
@@ -916,9 +909,9 @@ xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t *const stanza,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name_and_ns(xmpp_stanza_t *const stanza,
|
||||
const char *const name,
|
||||
const char *const ns)
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name_and_ns(xmpp_stanza_t *stanza,
|
||||
const char *name,
|
||||
const char *ns)
|
||||
{
|
||||
xmpp_stanza_t *child;
|
||||
const char *child_ns;
|
||||
@@ -947,7 +940,7 @@ xmpp_stanza_t *xmpp_stanza_get_child_by_name_and_ns(xmpp_stanza_t *const stanza,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t *const stanza)
|
||||
xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t *stanza)
|
||||
{
|
||||
return stanza->children;
|
||||
}
|
||||
@@ -960,7 +953,7 @@ xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_stanza_get_next(xmpp_stanza_t *const stanza)
|
||||
xmpp_stanza_t *xmpp_stanza_get_next(xmpp_stanza_t *stanza)
|
||||
{
|
||||
return stanza->next;
|
||||
}
|
||||
@@ -976,7 +969,7 @@ xmpp_stanza_t *xmpp_stanza_get_next(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
char *xmpp_stanza_get_text(xmpp_stanza_t *const stanza)
|
||||
char *xmpp_stanza_get_text(xmpp_stanza_t *stanza)
|
||||
{
|
||||
size_t len, clen;
|
||||
xmpp_stanza_t *child;
|
||||
@@ -1027,7 +1020,7 @@ char *xmpp_stanza_get_text(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
const char *xmpp_stanza_get_text_ptr(xmpp_stanza_t *const stanza)
|
||||
const char *xmpp_stanza_get_text_ptr(xmpp_stanza_t *stanza)
|
||||
{
|
||||
if (stanza->type == XMPP_STANZA_TEXT)
|
||||
return stanza->data;
|
||||
@@ -1046,7 +1039,7 @@ const char *xmpp_stanza_get_text_ptr(xmpp_stanza_t *const stanza)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_set_id(xmpp_stanza_t *const stanza, const char *const id)
|
||||
int xmpp_stanza_set_id(xmpp_stanza_t *stanza, const char *id)
|
||||
{
|
||||
return xmpp_stanza_set_attribute(stanza, "id", id);
|
||||
}
|
||||
@@ -1062,7 +1055,7 @@ int xmpp_stanza_set_id(xmpp_stanza_t *const stanza, const char *const id)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_set_type(xmpp_stanza_t *const stanza, const char *const type)
|
||||
int xmpp_stanza_set_type(xmpp_stanza_t *stanza, const char *type)
|
||||
{
|
||||
return xmpp_stanza_set_attribute(stanza, "type", type);
|
||||
}
|
||||
@@ -1079,7 +1072,7 @@ int xmpp_stanza_set_type(xmpp_stanza_t *const stanza, const char *const type)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_set_to(xmpp_stanza_t *const stanza, const char *const to)
|
||||
int xmpp_stanza_set_to(xmpp_stanza_t *stanza, const char *to)
|
||||
{
|
||||
return xmpp_stanza_set_attribute(stanza, "to", to);
|
||||
}
|
||||
@@ -1096,7 +1089,7 @@ int xmpp_stanza_set_to(xmpp_stanza_t *const stanza, const char *const to)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_set_from(xmpp_stanza_t *const stanza, const char *const from)
|
||||
int xmpp_stanza_set_from(xmpp_stanza_t *stanza, const char *from)
|
||||
{
|
||||
return xmpp_stanza_set_attribute(stanza, "from", from);
|
||||
}
|
||||
@@ -1112,8 +1105,7 @@ int xmpp_stanza_set_from(xmpp_stanza_t *const stanza, const char *const from)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
const char *xmpp_stanza_get_attribute(xmpp_stanza_t *const stanza,
|
||||
const char *const name)
|
||||
const char *xmpp_stanza_get_attribute(xmpp_stanza_t *stanza, const char *name)
|
||||
{
|
||||
if (stanza->type != XMPP_STANZA_TAG)
|
||||
return NULL;
|
||||
@@ -1133,8 +1125,7 @@ const char *xmpp_stanza_get_attribute(xmpp_stanza_t *const stanza,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_stanza_del_attribute(xmpp_stanza_t *const stanza,
|
||||
const char *const name)
|
||||
int xmpp_stanza_del_attribute(xmpp_stanza_t *stanza, const char *name)
|
||||
{
|
||||
if (stanza->type != XMPP_STANZA_TAG)
|
||||
return -1;
|
||||
@@ -1157,7 +1148,7 @@ int xmpp_stanza_del_attribute(xmpp_stanza_t *const stanza,
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t *const stanza)
|
||||
xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t *stanza)
|
||||
{
|
||||
xmpp_stanza_t *copy = NULL;
|
||||
const char *from;
|
||||
@@ -1212,10 +1203,10 @@ copy_error:
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_stanza_reply_error(xmpp_stanza_t *const stanza,
|
||||
const char *const error_type,
|
||||
const char *const condition,
|
||||
const char *const text)
|
||||
xmpp_stanza_t *xmpp_stanza_reply_error(xmpp_stanza_t *stanza,
|
||||
const char *error_type,
|
||||
const char *condition,
|
||||
const char *text)
|
||||
{
|
||||
xmpp_ctx_t *ctx = stanza->ctx;
|
||||
xmpp_stanza_t *reply = NULL;
|
||||
@@ -1277,10 +1268,10 @@ quit_err:
|
||||
}
|
||||
|
||||
static xmpp_stanza_t *_stanza_new_with_attrs(xmpp_ctx_t *ctx,
|
||||
const char *const name,
|
||||
const char *const type,
|
||||
const char *const id,
|
||||
const char *const to)
|
||||
const char *name,
|
||||
const char *type,
|
||||
const char *id,
|
||||
const char *to)
|
||||
{
|
||||
xmpp_stanza_t *stanza = xmpp_stanza_new(ctx);
|
||||
int ret;
|
||||
@@ -1314,9 +1305,9 @@ static xmpp_stanza_t *_stanza_new_with_attrs(xmpp_ctx_t *ctx,
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_message_new(xmpp_ctx_t *ctx,
|
||||
const char *const type,
|
||||
const char *const to,
|
||||
const char *const id)
|
||||
const char *type,
|
||||
const char *to,
|
||||
const char *id)
|
||||
{
|
||||
return _stanza_new_with_attrs(ctx, "message", type, id, to);
|
||||
}
|
||||
@@ -1355,7 +1346,7 @@ char *xmpp_message_get_body(xmpp_stanza_t *msg)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
int xmpp_message_set_body(xmpp_stanza_t *msg, const char *const text)
|
||||
int xmpp_message_set_body(xmpp_stanza_t *msg, const char *text)
|
||||
{
|
||||
xmpp_ctx_t *ctx = msg->ctx;
|
||||
xmpp_stanza_t *body;
|
||||
@@ -1401,8 +1392,7 @@ int xmpp_message_set_body(xmpp_stanza_t *msg, const char *const text)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *
|
||||
xmpp_iq_new(xmpp_ctx_t *ctx, const char *const type, const char *const id)
|
||||
xmpp_stanza_t *xmpp_iq_new(xmpp_ctx_t *ctx, const char *type, const char *id)
|
||||
{
|
||||
return _stanza_new_with_attrs(ctx, "iq", type, id, NULL);
|
||||
}
|
||||
@@ -1433,9 +1423,8 @@ xmpp_stanza_t *xmpp_presence_new(xmpp_ctx_t *ctx)
|
||||
*
|
||||
* @ingroup Stanza
|
||||
*/
|
||||
xmpp_stanza_t *xmpp_error_new(xmpp_ctx_t *ctx,
|
||||
xmpp_error_type_t const type,
|
||||
const char *const text)
|
||||
xmpp_stanza_t *
|
||||
xmpp_error_new(xmpp_ctx_t *ctx, xmpp_error_type_t type, const char *text)
|
||||
{
|
||||
xmpp_stanza_t *error =
|
||||
_stanza_new_with_attrs(ctx, "stream:error", NULL, NULL, NULL);
|
||||
|
||||
@@ -27,6 +27,9 @@ void tls_shutdown(void);
|
||||
tls_t *tls_new(xmpp_conn_t *conn);
|
||||
void tls_free(tls_t *tls);
|
||||
|
||||
char *tls_id_on_xmppaddr(xmpp_conn_t *conn, unsigned int n);
|
||||
unsigned int tls_id_on_xmppaddr_num(xmpp_conn_t *conn);
|
||||
|
||||
int tls_set_credentials(tls_t *tls, const char *cafilename);
|
||||
|
||||
int tls_start(tls_t *tls);
|
||||
@@ -35,8 +38,8 @@ int tls_stop(tls_t *tls);
|
||||
int tls_error(tls_t *tls);
|
||||
|
||||
int tls_pending(tls_t *tls);
|
||||
int tls_read(tls_t *tls, void *const buff, const size_t len);
|
||||
int tls_write(tls_t *tls, const void *const buff, const size_t len);
|
||||
int tls_read(tls_t *tls, void *buff, size_t len);
|
||||
int tls_write(tls_t *tls, const void *buff, size_t len);
|
||||
|
||||
int tls_clear_pending_write(tls_t *tls);
|
||||
int tls_is_recoverable(int error);
|
||||
|
||||
@@ -33,6 +33,21 @@ void tls_shutdown(void)
|
||||
return;
|
||||
}
|
||||
|
||||
char *tls_id_on_xmppaddr(xmpp_conn_t *conn, unsigned int n)
|
||||
{
|
||||
UNUSED(conn);
|
||||
UNUSED(n);
|
||||
/* always fail */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int tls_id_on_xmppaddr_num(xmpp_conn_t *conn)
|
||||
{
|
||||
UNUSED(conn);
|
||||
/* always fail */
|
||||
return 0;
|
||||
}
|
||||
|
||||
tls_t *tls_new(xmpp_conn_t *conn)
|
||||
{
|
||||
UNUSED(conn);
|
||||
@@ -78,7 +93,7 @@ int tls_pending(tls_t *tls)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||
int tls_read(tls_t *tls, void *buff, size_t len)
|
||||
{
|
||||
UNUSED(tls);
|
||||
UNUSED(buff);
|
||||
@@ -86,7 +101,7 @@ int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tls_write(tls_t *tls, const void *const buff, const size_t len)
|
||||
int tls_write(tls_t *tls, const void *buff, size_t len)
|
||||
{
|
||||
UNUSED(tls);
|
||||
UNUSED(buff);
|
||||
|
||||
149
src/tls_gnutls.c
149
src/tls_gnutls.c
@@ -13,7 +13,10 @@
|
||||
* TLS implementation with GNUTLS
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
#include <gnutls/x509-ext.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "tls.h"
|
||||
@@ -27,6 +30,7 @@ struct _tls {
|
||||
sock_t sock;
|
||||
gnutls_session_t session;
|
||||
gnutls_certificate_credentials_t cred;
|
||||
gnutls_x509_crt_t client_cert;
|
||||
int lasterror;
|
||||
};
|
||||
|
||||
@@ -46,11 +50,135 @@ void tls_shutdown(void)
|
||||
gnutls_global_deinit();
|
||||
}
|
||||
|
||||
static gnutls_x509_crt_t _tls_load_cert(xmpp_conn_t *conn)
|
||||
{
|
||||
if (conn->tls && conn->tls->client_cert)
|
||||
return conn->tls->client_cert;
|
||||
gnutls_x509_crt_t cert;
|
||||
gnutls_datum_t data;
|
||||
int res;
|
||||
if (gnutls_x509_crt_init(&cert) < 0)
|
||||
return NULL;
|
||||
if (gnutls_load_file(conn->tls_client_cert, &data) < 0)
|
||||
goto LBL_ERR;
|
||||
res = gnutls_x509_crt_import(cert, &data, GNUTLS_X509_FMT_PEM);
|
||||
gnutls_free(data.data);
|
||||
if (res < 0)
|
||||
goto LBL_ERR;
|
||||
return cert;
|
||||
LBL_ERR:
|
||||
gnutls_x509_crt_deinit(cert);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _tls_free_cert(xmpp_conn_t *conn, gnutls_x509_crt_t cert)
|
||||
{
|
||||
if (conn->tls && conn->tls->client_cert == cert)
|
||||
return;
|
||||
gnutls_x509_crt_deinit(cert);
|
||||
}
|
||||
|
||||
static int _tls_get_id_on_xmppaddr(xmpp_conn_t *conn,
|
||||
gnutls_x509_crt_t cert,
|
||||
unsigned int n,
|
||||
char **ret)
|
||||
{
|
||||
gnutls_datum_t san;
|
||||
size_t name_len, oid_len;
|
||||
char oid[128], name[128];
|
||||
name_len = oid_len = 128;
|
||||
int res =
|
||||
gnutls_x509_crt_get_subject_alt_name(cert, n, name, &name_len, NULL);
|
||||
if (res == GNUTLS_SAN_OTHERNAME_XMPP) {
|
||||
/* This is the happy flow path with fixed GnuTLS.
|
||||
* While implementing this I stumbled over an issue in GnuTLS
|
||||
* which lead to
|
||||
* https://gitlab.com/gnutls/gnutls/-/merge_requests/1397
|
||||
*/
|
||||
if (ret) {
|
||||
*ret = xmpp_strdup(conn->ctx, name);
|
||||
}
|
||||
return GNUTLS_SAN_OTHERNAME_XMPP;
|
||||
}
|
||||
if (res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
|
||||
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
||||
if (res != GNUTLS_SAN_OTHERNAME)
|
||||
return GNUTLS_E_X509_UNKNOWN_SAN;
|
||||
res = gnutls_x509_crt_get_subject_alt_othername_oid(cert, n, oid, &oid_len);
|
||||
if (res == GNUTLS_SAN_OTHERNAME_XMPP) {
|
||||
gnutls_datum_t xmpp_addr;
|
||||
san.data = (unsigned char *)name;
|
||||
san.size = name_len;
|
||||
res = gnutls_x509_othername_to_virtual(oid, &san, NULL, &xmpp_addr);
|
||||
if (res < 0) {
|
||||
gnutls_free(xmpp_addr.data);
|
||||
return GNUTLS_E_MEMORY_ERROR;
|
||||
}
|
||||
if (ret) {
|
||||
*ret = xmpp_strdup(conn->ctx, (char *)xmpp_addr.data);
|
||||
}
|
||||
gnutls_free(xmpp_addr.data);
|
||||
return GNUTLS_SAN_OTHERNAME_XMPP;
|
||||
}
|
||||
return GNUTLS_E_X509_UNKNOWN_SAN;
|
||||
}
|
||||
|
||||
int _tls_id_on_xmppaddr(xmpp_conn_t *conn,
|
||||
gnutls_x509_crt_t cert,
|
||||
unsigned int n,
|
||||
char **ret)
|
||||
{
|
||||
int res = GNUTLS_E_SUCCESS;
|
||||
unsigned int i, j;
|
||||
for (i = j = 0; res != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; ++i) {
|
||||
res = _tls_get_id_on_xmppaddr(conn, cert, i, NULL);
|
||||
if (res == GNUTLS_SAN_OTHERNAME_XMPP) {
|
||||
if (j == n) {
|
||||
res = _tls_get_id_on_xmppaddr(conn, cert, i, ret);
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Search through the SubjectAlternativeNames and return the next
|
||||
* id-on-xmppAddr element starting from `n`.
|
||||
*/
|
||||
char *tls_id_on_xmppaddr(xmpp_conn_t *conn, unsigned int n)
|
||||
{
|
||||
char *ret = NULL;
|
||||
gnutls_x509_crt_t cert = _tls_load_cert(conn);
|
||||
if (cert == NULL)
|
||||
return NULL;
|
||||
_tls_id_on_xmppaddr(conn, cert, n, &ret);
|
||||
_tls_free_cert(conn, cert);
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int tls_id_on_xmppaddr_num(xmpp_conn_t *conn)
|
||||
{
|
||||
unsigned int ret = 0, n;
|
||||
int res = GNUTLS_E_SUCCESS;
|
||||
gnutls_x509_crt_t cert = _tls_load_cert(conn);
|
||||
if (cert == NULL)
|
||||
return 0;
|
||||
for (n = 0; res != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; ++n) {
|
||||
res = _tls_id_on_xmppaddr(conn, cert, n, NULL);
|
||||
if (res == GNUTLS_SAN_OTHERNAME_XMPP)
|
||||
ret++;
|
||||
}
|
||||
_tls_free_cert(conn, cert);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tls_t *tls_new(xmpp_conn_t *conn)
|
||||
{
|
||||
tls_t *tls = xmpp_alloc(conn->ctx, sizeof(tls_t));
|
||||
|
||||
if (tls) {
|
||||
memset(tls, 0, sizeof(*tls));
|
||||
tls->ctx = conn->ctx;
|
||||
tls->sock = conn->sock;
|
||||
gnutls_init(&tls->session, GNUTLS_CLIENT);
|
||||
@@ -58,6 +186,21 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
||||
gnutls_certificate_allocate_credentials(&tls->cred);
|
||||
tls_set_credentials(tls, CAFILE);
|
||||
|
||||
if (conn->tls_client_cert && conn->tls_client_key) {
|
||||
tls->client_cert = _tls_load_cert(conn);
|
||||
if (!tls->client_cert) {
|
||||
xmpp_error(tls->ctx, "tls",
|
||||
"could not read client certificate");
|
||||
gnutls_certificate_free_credentials(tls->cred);
|
||||
gnutls_deinit(tls->session);
|
||||
xmpp_free(tls->ctx, tls);
|
||||
return NULL;
|
||||
}
|
||||
gnutls_certificate_set_x509_key_file(
|
||||
tls->cred, conn->tls_client_cert, conn->tls_client_key,
|
||||
GNUTLS_X509_FMT_PEM);
|
||||
}
|
||||
|
||||
gnutls_set_default_priority(tls->session);
|
||||
|
||||
/* fixme: this may require setting a callback on win32? */
|
||||
@@ -69,6 +212,8 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
||||
|
||||
void tls_free(tls_t *tls)
|
||||
{
|
||||
if (tls->client_cert)
|
||||
gnutls_x509_crt_deinit(tls->client_cert);
|
||||
gnutls_deinit(tls->session);
|
||||
gnutls_certificate_free_credentials(tls->cred);
|
||||
xmpp_free(tls->ctx, tls);
|
||||
@@ -120,7 +265,7 @@ int tls_pending(tls_t *tls)
|
||||
return gnutls_record_check_pending(tls->session);
|
||||
}
|
||||
|
||||
int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||
int tls_read(tls_t *tls, void *buff, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -130,7 +275,7 @@ int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tls_write(tls_t *tls, const void *const buff, const size_t len)
|
||||
int tls_write(tls_t *tls, const void *buff, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
@@ -47,11 +47,34 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
static const unsigned char *ASN1_STRING_get0_data(ASN1_STRING *asn1)
|
||||
{
|
||||
return ASN1_STRING_data(asn1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10000000L
|
||||
static int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen,
|
||||
ASN1_OBJECT **poid,
|
||||
ASN1_TYPE **pvalue)
|
||||
{
|
||||
if (gen->type != GEN_OTHERNAME)
|
||||
return 0;
|
||||
if (poid)
|
||||
*poid = gen->d.otherName->type_id;
|
||||
if (pvalue)
|
||||
*pvalue = gen->d.otherName->value;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct _tls {
|
||||
xmpp_ctx_t *ctx;
|
||||
sock_t sock;
|
||||
SSL_CTX *ssl_ctx;
|
||||
SSL *ssl;
|
||||
X509 *client_cert;
|
||||
int lasterror;
|
||||
};
|
||||
|
||||
@@ -66,6 +89,10 @@ static const char *_tls_error_str(int error, const char **tbl, size_t tbl_size);
|
||||
static void _tls_set_error(tls_t *tls, int error);
|
||||
static void _tls_log_error(xmpp_ctx_t *ctx);
|
||||
static void _tls_dump_cert_info(tls_t *tls);
|
||||
static X509 *_tls_cert_read(xmpp_conn_t *conn);
|
||||
static int _tls_xaddr_nid(void);
|
||||
static int _tls_name_to_xmppaddr(GENERAL_NAME *name, char **res);
|
||||
static GENERAL_NAMES *_tls_cert_get_names(xmpp_conn_t *conn);
|
||||
|
||||
#define TLS_ERROR_STR(error, table) \
|
||||
_tls_error_str(error, table, ARRAY_SIZE(table))
|
||||
@@ -189,6 +216,8 @@ void tls_initialize(void)
|
||||
#else
|
||||
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
#endif
|
||||
/* init xmppAddr OID */
|
||||
_tls_xaddr_nid();
|
||||
}
|
||||
|
||||
void tls_shutdown(void)
|
||||
@@ -199,6 +228,7 @@ void tls_shutdown(void)
|
||||
* memory rather than cause random crashes of the main program.
|
||||
*/
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
OBJ_cleanup();
|
||||
ERR_free_strings();
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
@@ -218,6 +248,55 @@ int tls_error(tls_t *tls)
|
||||
return tls->lasterror;
|
||||
}
|
||||
|
||||
/** Search through the SubjectAlternativeNames and return the next
|
||||
* id-on-xmppAddr element starting from `n`.
|
||||
*/
|
||||
char *tls_id_on_xmppaddr(xmpp_conn_t *conn, unsigned int n)
|
||||
{
|
||||
char *ret = NULL;
|
||||
int i, j;
|
||||
GENERAL_NAMES *names = _tls_cert_get_names(conn);
|
||||
if (!names)
|
||||
return NULL;
|
||||
int num_names = sk_GENERAL_NAME_num(names);
|
||||
for (i = j = 0; i < num_names; ++i) {
|
||||
char *res;
|
||||
GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
|
||||
if (name == NULL)
|
||||
break;
|
||||
if (_tls_name_to_xmppaddr(name, &res))
|
||||
continue;
|
||||
if (j == (int)n) {
|
||||
xmpp_debug(conn->ctx, "tls", "extracted jid %s from id-on-xmppAddr",
|
||||
res);
|
||||
ret = xmpp_strdup(conn->ctx, res);
|
||||
OPENSSL_free(res);
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
OPENSSL_free(res);
|
||||
}
|
||||
GENERAL_NAMES_free(names);
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int tls_id_on_xmppaddr_num(xmpp_conn_t *conn)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
GENERAL_NAMES *names = _tls_cert_get_names(conn);
|
||||
if (!names)
|
||||
return 0;
|
||||
int j, num_names = sk_GENERAL_NAME_num(names);
|
||||
for (j = 0; j < num_names; ++j) {
|
||||
GENERAL_NAME *name = sk_GENERAL_NAME_value(names, j);
|
||||
if (_tls_name_to_xmppaddr(name, NULL))
|
||||
continue;
|
||||
ret++;
|
||||
}
|
||||
GENERAL_NAMES_free(names);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tls_t *tls_new(xmpp_conn_t *conn)
|
||||
{
|
||||
tls_t *tls = xmpp_alloc(conn->ctx, sizeof(*tls));
|
||||
@@ -249,7 +328,23 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
||||
SSL_CTX_set_options(tls->ssl_ctx, SSL_OP_NO_SSLv3); /* POODLE */
|
||||
SSL_CTX_set_options(tls->ssl_ctx, SSL_OP_NO_TLSv1); /* BEAST */
|
||||
|
||||
SSL_CTX_set_client_cert_cb(tls->ssl_ctx, NULL);
|
||||
if (conn->tls_client_cert && conn->tls_client_key) {
|
||||
tls->client_cert = _tls_cert_read(conn);
|
||||
if (!tls->client_cert) {
|
||||
xmpp_error(tls->ctx, "tls",
|
||||
"could not read client certificate");
|
||||
goto err_free_ctx;
|
||||
}
|
||||
|
||||
SSL_CTX_use_certificate_file(tls->ssl_ctx, conn->tls_client_cert,
|
||||
SSL_FILETYPE_PEM);
|
||||
SSL_CTX_use_PrivateKey_file(tls->ssl_ctx, conn->tls_client_key,
|
||||
SSL_FILETYPE_PEM);
|
||||
} else {
|
||||
/* If the server asks for a client certificate, don't send one. */
|
||||
SSL_CTX_set_client_cert_cb(tls->ssl_ctx, NULL);
|
||||
}
|
||||
|
||||
SSL_CTX_set_mode(tls->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||
|
||||
ret = SSL_CTX_set_default_verify_paths(tls->ssl_ctx);
|
||||
@@ -261,12 +356,12 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
||||
*/
|
||||
xmpp_error(tls->ctx, "tls",
|
||||
"SSL_CTX_set_default_verify_paths() failed");
|
||||
goto err_free_ctx;
|
||||
goto err_free_cert;
|
||||
}
|
||||
|
||||
tls->ssl = SSL_new(tls->ssl_ctx);
|
||||
if (tls->ssl == NULL)
|
||||
goto err_free_ctx;
|
||||
goto err_free_cert;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0908060L && !defined(OPENSSL_NO_TLSEXT)
|
||||
/* Enable SNI. */
|
||||
@@ -301,6 +396,8 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
||||
|
||||
err_free_ssl:
|
||||
SSL_free(tls->ssl);
|
||||
err_free_cert:
|
||||
X509_free(tls->client_cert);
|
||||
err_free_ctx:
|
||||
SSL_CTX_free(tls->ssl_ctx);
|
||||
err:
|
||||
@@ -312,6 +409,7 @@ err:
|
||||
void tls_free(tls_t *tls)
|
||||
{
|
||||
SSL_free(tls->ssl);
|
||||
X509_free(tls->client_cert);
|
||||
SSL_CTX_free(tls->ssl_ctx);
|
||||
xmpp_free(tls->ctx, tls);
|
||||
}
|
||||
@@ -405,7 +503,7 @@ int tls_pending(tls_t *tls)
|
||||
return SSL_pending(tls->ssl);
|
||||
}
|
||||
|
||||
int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||
int tls_read(tls_t *tls, void *buff, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -415,7 +513,7 @@ int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tls_write(tls_t *tls, const void *const buff, const size_t len)
|
||||
int tls_write(tls_t *tls, const void *buff, size_t len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -509,3 +607,92 @@ static void _tls_dump_cert_info(tls_t *tls)
|
||||
X509_free(cert);
|
||||
}
|
||||
}
|
||||
|
||||
static X509 *_tls_cert_read(xmpp_conn_t *conn)
|
||||
{
|
||||
if (conn->tls && conn->tls->client_cert)
|
||||
return conn->tls->client_cert;
|
||||
BIO *f = BIO_new_file(conn->tls_client_cert, "r");
|
||||
if (!f) {
|
||||
xmpp_debug(conn->ctx, "tls", "f == NULL");
|
||||
return NULL;
|
||||
}
|
||||
X509 *c = PEM_read_bio_X509(f, NULL, NULL, NULL);
|
||||
BIO_free(f);
|
||||
if (!c) {
|
||||
unsigned long error;
|
||||
while ((error = ERR_get_error()) != 0) {
|
||||
xmpp_debug(conn->ctx, "tls", "c == NULL: %s",
|
||||
ERR_error_string(error, NULL));
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static int _tls_xaddr_nid(void)
|
||||
{
|
||||
static int xaddr_nid = NID_undef;
|
||||
if (xaddr_nid == NID_undef) {
|
||||
xaddr_nid = OBJ_sn2nid("id-on-xmppAddr");
|
||||
}
|
||||
if (xaddr_nid == NID_undef) {
|
||||
xaddr_nid = OBJ_create("1.3.6.1.5.5.7.8.5", "id-on-xmppAddr",
|
||||
"XmppAddr Identifier");
|
||||
}
|
||||
return xaddr_nid;
|
||||
}
|
||||
|
||||
static GENERAL_NAMES *_tls_cert_get_names(xmpp_conn_t *conn)
|
||||
{
|
||||
X509 *client_cert;
|
||||
GENERAL_NAMES *names = NULL;
|
||||
client_cert = _tls_cert_read(conn);
|
||||
if (!client_cert)
|
||||
return NULL;
|
||||
int san = X509_get_ext_by_NID(client_cert, NID_subject_alt_name, 0);
|
||||
X509_EXTENSION *san_ext = X509_get_ext(client_cert, san);
|
||||
if (!san_ext)
|
||||
goto OUT;
|
||||
ASN1_OCTET_STRING *data = X509_EXTENSION_get_data(san_ext);
|
||||
if (!data)
|
||||
goto OUT;
|
||||
const unsigned char *d = ASN1_STRING_get0_data(data);
|
||||
if (!d)
|
||||
goto OUT;
|
||||
names = d2i_GENERAL_NAMES(NULL, &d, ASN1_STRING_length(data));
|
||||
OUT:
|
||||
if (!conn->tls || !conn->tls->client_cert)
|
||||
X509_free(client_cert);
|
||||
return names;
|
||||
}
|
||||
|
||||
/** Convert GENERAL_NAME* to a string
|
||||
*
|
||||
* This checks whether the GENERAL_NAME* that is given has the
|
||||
* correct id-on-xmppAddr set and then optionally converts this
|
||||
* form ASN.1 to a string/char*.
|
||||
*
|
||||
* When `res` pointer is set to NULL this method doesn't allocate
|
||||
* the result but only checks whether it is in the correct format.
|
||||
*
|
||||
* @param name Pointer to the GENERAL_NAME that shall be converted
|
||||
* @param res Result-pointer (optional, can be NULL)
|
||||
*
|
||||
* @return classic Unix style - 0=success, 1=error
|
||||
*/
|
||||
static int _tls_name_to_xmppaddr(GENERAL_NAME *name, char **res)
|
||||
{
|
||||
ASN1_OBJECT *oid;
|
||||
ASN1_TYPE *val;
|
||||
if (!name || name->type != GEN_OTHERNAME)
|
||||
return 1;
|
||||
if (GENERAL_NAME_get0_otherName(name, &oid, &val) == 0)
|
||||
return 1;
|
||||
if (OBJ_obj2nid(oid) != _tls_xaddr_nid() || !val)
|
||||
return 1;
|
||||
if (!res)
|
||||
return 0;
|
||||
if (ASN1_STRING_to_UTF8((unsigned char **)res, val->value.asn1_string) < 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,21 @@ void tls_shutdown(void)
|
||||
return;
|
||||
}
|
||||
|
||||
char *tls_id_on_xmppaddr(xmpp_conn_t *conn, unsigned int n)
|
||||
{
|
||||
UNUSED(n);
|
||||
/* always fail */
|
||||
xmpp_error(conn->ctx, "tls", "Client-Authentication not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int tls_id_on_xmppaddr_num(xmpp_conn_t *conn)
|
||||
{
|
||||
/* always fail */
|
||||
xmpp_error(conn->ctx, "tls", "Client-Authentication not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
tls_t *tls_new(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_ctx_t *ctx = conn->ctx;
|
||||
@@ -412,7 +427,7 @@ int tls_pending(tls_t *tls)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||
int tls_read(tls_t *tls, void *buff, size_t len)
|
||||
{
|
||||
int bytes;
|
||||
|
||||
@@ -557,7 +572,7 @@ int tls_clear_pending_write(tls_t *tls)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tls_write(tls_t *tls, const void *const buff, const size_t len)
|
||||
int tls_write(tls_t *tls, const void *buff, size_t len)
|
||||
{
|
||||
SecBufferDesc sbdenc;
|
||||
SecBuffer sbenc[4];
|
||||
|
||||
252
src/tls_securetransport.c
Normal file
252
src/tls_securetransport.c
Normal file
@@ -0,0 +1,252 @@
|
||||
// Secure Transport implementation of TLS by Christopher A. Taylor (2013)
|
||||
|
||||
#include <Security/Security.h>
|
||||
#include <Security/SecureTransport.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "tls.h"
|
||||
#include "sock.h"
|
||||
|
||||
struct _tls {
|
||||
xmpp_ctx_t *ctx;
|
||||
sock_t sock;
|
||||
|
||||
SSLContextRef sslctx;
|
||||
};
|
||||
|
||||
void tls_initialize(void)
|
||||
{
|
||||
}
|
||||
|
||||
void tls_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
char *tls_id_on_xmppaddr(xmpp_conn_t *conn, unsigned int n)
|
||||
{
|
||||
UNUSED(n);
|
||||
/* always fail */
|
||||
xmpp_error(conn->ctx, "tls", "Client-Authentication not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int tls_id_on_xmppaddr_num(xmpp_conn_t *conn)
|
||||
{
|
||||
/* always fail */
|
||||
xmpp_error(conn->ctx, "tls", "Client-Authentication not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
OSStatus MySSLReadFunction(SSLConnectionRef connection, void *data, size_t *dataLength) {
|
||||
size_t bytesToGo = *dataLength;
|
||||
size_t initLen = bytesToGo;
|
||||
UInt8 *currData = (UInt8 *)data;
|
||||
/*int sock = *(int *)connection;*/
|
||||
tls_t *connssl = (tls_t *)connection;
|
||||
int sock = connssl->sock;
|
||||
OSStatus rtn = noErr;
|
||||
size_t bytesRead;
|
||||
ssize_t rrtn;
|
||||
int theErr;
|
||||
|
||||
*dataLength = 0;
|
||||
|
||||
for(;;) {
|
||||
bytesRead = 0;
|
||||
rrtn = read(sock, currData, bytesToGo);
|
||||
if(rrtn <= 0) {
|
||||
/* this is guesswork... */
|
||||
theErr = errno;
|
||||
if(rrtn == 0) { /* EOF = server hung up */
|
||||
/* the framework will turn this into errSSLClosedNoNotify */
|
||||
rtn = errSSLClosedGraceful;
|
||||
}
|
||||
else /* do the switch */
|
||||
switch(theErr) {
|
||||
case ENOENT:
|
||||
/* connection closed */
|
||||
rtn = errSSLClosedGraceful;
|
||||
break;
|
||||
case ECONNRESET:
|
||||
rtn = errSSLClosedAbort;
|
||||
break;
|
||||
case EAGAIN:
|
||||
rtn = errSSLWouldBlock;
|
||||
//connssl->ssl_direction = false;
|
||||
break;
|
||||
default:
|
||||
rtn = errSSLClosedAbort;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
bytesRead = rrtn;
|
||||
}
|
||||
bytesToGo -= bytesRead;
|
||||
currData += bytesRead;
|
||||
|
||||
if(bytesToGo == 0) {
|
||||
/* filled buffer with incoming data, done */
|
||||
break;
|
||||
}
|
||||
}
|
||||
*dataLength = initLen - bytesToGo;
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
OSStatus MySSLWriteFunction(SSLConnectionRef connection, const void *data, size_t *dataLength) {
|
||||
size_t bytesSent = 0;
|
||||
/*int sock = *(int *)connection;*/
|
||||
tls_t *connssl = (tls_t *)connection;
|
||||
int sock = connssl->sock;
|
||||
ssize_t length;
|
||||
size_t dataLen = *dataLength;
|
||||
const UInt8 *dataPtr = (UInt8 *)data;
|
||||
OSStatus ortn;
|
||||
int theErr;
|
||||
|
||||
*dataLength = 0;
|
||||
|
||||
do {
|
||||
length = write(sock,
|
||||
(char*)dataPtr + bytesSent,
|
||||
dataLen - bytesSent);
|
||||
} while((length > 0) &&
|
||||
( (bytesSent += length) < dataLen) );
|
||||
|
||||
if(length <= 0) {
|
||||
theErr = errno;
|
||||
if(theErr == EAGAIN) {
|
||||
ortn = errSSLWouldBlock;
|
||||
//connssl->ssl_direction = true;
|
||||
}
|
||||
else {
|
||||
ortn = errSSLClosedAbort;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ortn = noErr;
|
||||
}
|
||||
*dataLength = bytesSent;
|
||||
return ortn;
|
||||
}
|
||||
|
||||
tls_t *tls_new(xmpp_conn_t *conn)
|
||||
{
|
||||
tls_t *tls = xmpp_alloc(conn->ctx, sizeof(tls_t));
|
||||
|
||||
if (tls) {
|
||||
tls->ctx = conn->ctx;
|
||||
tls->sock = conn->sock;
|
||||
tls->sslctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
|
||||
|
||||
SSLSetIOFuncs(tls->sslctx, MySSLReadFunction, MySSLWriteFunction);
|
||||
|
||||
SSLSetConnection(tls->sslctx, tls);
|
||||
}
|
||||
|
||||
return tls;
|
||||
}
|
||||
|
||||
void tls_free(tls_t *tls)
|
||||
{
|
||||
CFRelease(tls->sslctx);
|
||||
|
||||
xmpp_free(tls->ctx, tls);
|
||||
}
|
||||
|
||||
int tls_set_credentials(tls_t *tls, const char *cafilename)
|
||||
{
|
||||
/*
|
||||
Not implemented in OpenSSL version so we should not need it either.
|
||||
But if we want to do it here's a place to start:
|
||||
|
||||
FILE * ret = fopen(cafilename, options);
|
||||
void *data = malloc(bytes);
|
||||
fread(data, 1, bytes, ret);
|
||||
fclose(ret);
|
||||
NSData *myCertData = [NSData dataWithBytesNoCopy:data length:bytes]; <- requires -ObjC compile option?
|
||||
|
||||
SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, myCertData);
|
||||
CFArrayRef certRefs = CFArrayCreate(kCFAllocatorDefault, (const void **)&cert, 1, NULL);
|
||||
|
||||
SSLSetCertificate(tls->sslctx, certRefs);
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tls_start(tls_t *tls)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Since we're non-blocking, loop the connect call until it
|
||||
succeeds or fails */
|
||||
do {
|
||||
ret = SSLHandshake(tls->sslctx);
|
||||
} while (ret == errSSLWouldBlock);
|
||||
|
||||
return ret < 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
int tls_stop(tls_t *tls)
|
||||
{
|
||||
SSLClose(tls->sslctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_is_recoverable(int error)
|
||||
{
|
||||
switch (error) {
|
||||
case errSSLWouldBlock:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int tls_error(tls_t *tls)
|
||||
{
|
||||
/* todo: some kind of error polling/dump */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tls_pending(tls_t *tls)
|
||||
{
|
||||
size_t buffer;
|
||||
|
||||
if (SSLGetBufferedReadSize(tls->sslctx, &buffer) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int tls_read(tls_t *tls, void * const buff, const size_t len)
|
||||
{
|
||||
size_t processed;
|
||||
|
||||
SSLRead(tls->sslctx, buff, len, &processed);
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
int tls_write(tls_t *tls, const void * const buff, const size_t len)
|
||||
{
|
||||
size_t processed;
|
||||
|
||||
SSLWrite(tls->sslctx, buff, len, &processed);
|
||||
|
||||
return processed;
|
||||
}
|
||||
|
||||
int tls_clear_pending_write(tls_t *tls)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
*
|
||||
* @return a new allocates string with the same data as s or NULL on error
|
||||
*/
|
||||
char *xmpp_strdup(const xmpp_ctx_t *const ctx, const char *const s)
|
||||
char *xmpp_strdup(const xmpp_ctx_t *ctx, const char *s)
|
||||
{
|
||||
size_t len;
|
||||
char *copy;
|
||||
@@ -135,7 +135,7 @@ uint64_t time_elapsed(uint64_t t1, uint64_t t2)
|
||||
*
|
||||
* @param conn a Strophe connection object
|
||||
*/
|
||||
void disconnect_mem_error(xmpp_conn_t *const conn)
|
||||
void disconnect_mem_error(xmpp_conn_t *conn)
|
||||
{
|
||||
xmpp_error(conn->ctx, "xmpp", "Memory allocation error");
|
||||
xmpp_disconnect(conn);
|
||||
|
||||
275
strophe.h
275
strophe.h
@@ -122,18 +122,17 @@ typedef struct _xmpp_log_t xmpp_log_t;
|
||||
/* opaque run time context containing the above hooks */
|
||||
typedef struct _xmpp_ctx_t xmpp_ctx_t;
|
||||
|
||||
xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t *const mem,
|
||||
const xmpp_log_t *const log);
|
||||
void xmpp_ctx_free(xmpp_ctx_t *const ctx);
|
||||
xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t *mem, const xmpp_log_t *log);
|
||||
void xmpp_ctx_free(xmpp_ctx_t *ctx);
|
||||
|
||||
/* free some blocks returned by other APIs, for example the
|
||||
buffer you get from xmpp_stanza_to_text */
|
||||
void xmpp_free(const xmpp_ctx_t *const ctx, void *p);
|
||||
void xmpp_free(const xmpp_ctx_t *ctx, void *p);
|
||||
|
||||
struct _xmpp_mem_t {
|
||||
void *(*alloc)(const size_t size, void *const userdata);
|
||||
void (*free)(void *p, void *const userdata);
|
||||
void *(*realloc)(void *p, const size_t size, void *const userdata);
|
||||
void *(*alloc)(size_t size, void *userdata);
|
||||
void (*free)(void *p, void *userdata);
|
||||
void *(*realloc)(void *p, size_t size, void *userdata);
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
@@ -146,10 +145,10 @@ typedef enum {
|
||||
|
||||
typedef enum { XMPP_UNKNOWN, XMPP_CLIENT, XMPP_COMPONENT } xmpp_conn_type_t;
|
||||
|
||||
typedef void (*xmpp_log_handler)(void *const userdata,
|
||||
const xmpp_log_level_t level,
|
||||
const char *const area,
|
||||
const char *const msg);
|
||||
typedef void (*xmpp_log_handler)(void *userdata,
|
||||
xmpp_log_level_t level,
|
||||
const char *area,
|
||||
const char *msg);
|
||||
|
||||
struct _xmpp_log_t {
|
||||
xmpp_log_handler handler;
|
||||
@@ -219,112 +218,108 @@ typedef struct {
|
||||
xmpp_stanza_t *stanza;
|
||||
} xmpp_stream_error_t;
|
||||
|
||||
typedef void (*xmpp_conn_handler)(xmpp_conn_t *const conn,
|
||||
const xmpp_conn_event_t event,
|
||||
const int error,
|
||||
xmpp_stream_error_t *const stream_error,
|
||||
void *const userdata);
|
||||
typedef void (*xmpp_conn_handler)(xmpp_conn_t *conn,
|
||||
xmpp_conn_event_t event,
|
||||
int error,
|
||||
xmpp_stream_error_t *stream_error,
|
||||
void *userdata);
|
||||
|
||||
void xmpp_send_error(xmpp_conn_t *const conn,
|
||||
xmpp_error_type_t const type,
|
||||
char *const text);
|
||||
xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t *const ctx);
|
||||
xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t *const conn);
|
||||
int xmpp_conn_release(xmpp_conn_t *const conn);
|
||||
void xmpp_send_error(xmpp_conn_t *conn, xmpp_error_type_t type, char *text);
|
||||
xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t *ctx);
|
||||
xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t *conn);
|
||||
int xmpp_conn_release(xmpp_conn_t *conn);
|
||||
|
||||
long xmpp_conn_get_flags(const xmpp_conn_t *const conn);
|
||||
int xmpp_conn_set_flags(xmpp_conn_t *const conn, long flags);
|
||||
const char *xmpp_conn_get_jid(const xmpp_conn_t *const conn);
|
||||
const char *xmpp_conn_get_bound_jid(const xmpp_conn_t *const conn);
|
||||
void xmpp_conn_set_jid(xmpp_conn_t *const conn, const char *const jid);
|
||||
const char *xmpp_conn_get_pass(const xmpp_conn_t *const conn);
|
||||
void xmpp_conn_set_pass(xmpp_conn_t *const conn, const char *const pass);
|
||||
xmpp_ctx_t *xmpp_conn_get_context(xmpp_conn_t *const conn);
|
||||
void xmpp_conn_disable_tls(xmpp_conn_t *const conn);
|
||||
int xmpp_conn_is_secured(xmpp_conn_t *const conn);
|
||||
void xmpp_conn_set_keepalive(xmpp_conn_t *const conn,
|
||||
int timeout,
|
||||
int interval);
|
||||
int xmpp_conn_is_connecting(xmpp_conn_t *const conn);
|
||||
int xmpp_conn_is_connected(xmpp_conn_t *const conn);
|
||||
int xmpp_conn_is_disconnected(xmpp_conn_t *const conn);
|
||||
long xmpp_conn_get_flags(const xmpp_conn_t *conn);
|
||||
int xmpp_conn_set_flags(xmpp_conn_t *conn, long flags);
|
||||
const char *xmpp_conn_get_jid(const xmpp_conn_t *conn);
|
||||
const char *xmpp_conn_get_bound_jid(const xmpp_conn_t *conn);
|
||||
void xmpp_conn_set_jid(xmpp_conn_t *conn, const char *jid);
|
||||
void xmpp_conn_set_client_cert(xmpp_conn_t *conn,
|
||||
const char *cert,
|
||||
const char *key);
|
||||
unsigned int xmpp_conn_cert_xmppaddr_num(xmpp_conn_t *conn);
|
||||
char *xmpp_conn_cert_xmppaddr(xmpp_conn_t *conn, unsigned int n);
|
||||
const char *xmpp_conn_get_pass(const xmpp_conn_t *conn);
|
||||
void xmpp_conn_set_pass(xmpp_conn_t *conn, const char *pass);
|
||||
xmpp_ctx_t *xmpp_conn_get_context(xmpp_conn_t *conn);
|
||||
void xmpp_conn_disable_tls(xmpp_conn_t *conn);
|
||||
int xmpp_conn_is_secured(xmpp_conn_t *conn);
|
||||
void xmpp_conn_set_keepalive(xmpp_conn_t *conn, int timeout, int interval);
|
||||
int xmpp_conn_is_connecting(xmpp_conn_t *conn);
|
||||
int xmpp_conn_is_connected(xmpp_conn_t *conn);
|
||||
int xmpp_conn_is_disconnected(xmpp_conn_t *conn);
|
||||
|
||||
int xmpp_connect_client(xmpp_conn_t *const conn,
|
||||
const char *const altdomain,
|
||||
int xmpp_connect_client(xmpp_conn_t *conn,
|
||||
const char *altdomain,
|
||||
unsigned short altport,
|
||||
xmpp_conn_handler callback,
|
||||
void *const userdata);
|
||||
void *userdata);
|
||||
|
||||
int xmpp_connect_component(xmpp_conn_t *const conn,
|
||||
const char *const server,
|
||||
int xmpp_connect_component(xmpp_conn_t *conn,
|
||||
const char *server,
|
||||
unsigned short port,
|
||||
xmpp_conn_handler callback,
|
||||
void *const userdata);
|
||||
void *userdata);
|
||||
|
||||
int xmpp_connect_raw(xmpp_conn_t *const conn,
|
||||
const char *const altdomain,
|
||||
int xmpp_connect_raw(xmpp_conn_t *conn,
|
||||
const char *altdomain,
|
||||
unsigned short altport,
|
||||
xmpp_conn_handler callback,
|
||||
void *const userdata);
|
||||
int xmpp_conn_open_stream_default(xmpp_conn_t *const conn);
|
||||
int xmpp_conn_open_stream(xmpp_conn_t *const conn,
|
||||
void *userdata);
|
||||
int xmpp_conn_open_stream_default(xmpp_conn_t *conn);
|
||||
int xmpp_conn_open_stream(xmpp_conn_t *conn,
|
||||
char **attributes,
|
||||
size_t attributes_len);
|
||||
int xmpp_conn_tls_start(xmpp_conn_t *const conn);
|
||||
int xmpp_conn_tls_start(xmpp_conn_t *conn);
|
||||
|
||||
void xmpp_disconnect(xmpp_conn_t *const conn);
|
||||
void xmpp_disconnect(xmpp_conn_t *conn);
|
||||
|
||||
void xmpp_send(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza);
|
||||
void xmpp_send(xmpp_conn_t *conn, xmpp_stanza_t *stanza);
|
||||
|
||||
void xmpp_send_raw_string(xmpp_conn_t *const conn, const char *const fmt, ...);
|
||||
void xmpp_send_raw(xmpp_conn_t *const conn,
|
||||
const char *const data,
|
||||
const size_t len);
|
||||
void xmpp_send_raw_string(xmpp_conn_t *conn, const char *fmt, ...);
|
||||
void xmpp_send_raw(xmpp_conn_t *conn, const char *data, size_t len);
|
||||
|
||||
/* handlers */
|
||||
|
||||
/* if the handler returns false it is removed */
|
||||
typedef int (*xmpp_timed_handler)(xmpp_conn_t *const conn,
|
||||
void *const userdata);
|
||||
typedef int (*xmpp_timed_handler)(xmpp_conn_t *conn, void *userdata);
|
||||
|
||||
void xmpp_timed_handler_add(xmpp_conn_t *const conn,
|
||||
void xmpp_timed_handler_add(xmpp_conn_t *conn,
|
||||
xmpp_timed_handler handler,
|
||||
const unsigned long period,
|
||||
void *const userdata);
|
||||
void xmpp_timed_handler_delete(xmpp_conn_t *const conn,
|
||||
xmpp_timed_handler handler);
|
||||
unsigned long period,
|
||||
void *userdata);
|
||||
void xmpp_timed_handler_delete(xmpp_conn_t *conn, xmpp_timed_handler handler);
|
||||
|
||||
/* if the handler returns false it is removed */
|
||||
typedef int (*xmpp_global_timed_handler)(xmpp_ctx_t *const ctx,
|
||||
void *const userdata);
|
||||
typedef int (*xmpp_global_timed_handler)(xmpp_ctx_t *ctx, void *userdata);
|
||||
|
||||
void xmpp_global_timed_handler_add(xmpp_ctx_t *const ctx,
|
||||
void xmpp_global_timed_handler_add(xmpp_ctx_t *ctx,
|
||||
xmpp_global_timed_handler handler,
|
||||
const unsigned long period,
|
||||
void *const userdata);
|
||||
void xmpp_global_timed_handler_delete(xmpp_ctx_t *const ctx,
|
||||
unsigned long period,
|
||||
void *userdata);
|
||||
void xmpp_global_timed_handler_delete(xmpp_ctx_t *ctx,
|
||||
xmpp_global_timed_handler handler);
|
||||
|
||||
/* if the handler returns false it is removed */
|
||||
typedef int (*xmpp_handler)(xmpp_conn_t *const conn,
|
||||
xmpp_stanza_t *const stanza,
|
||||
void *const userdata);
|
||||
typedef int (*xmpp_handler)(xmpp_conn_t *conn,
|
||||
xmpp_stanza_t *stanza,
|
||||
void *userdata);
|
||||
|
||||
void xmpp_handler_add(xmpp_conn_t *const conn,
|
||||
void xmpp_handler_add(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const ns,
|
||||
const char *const name,
|
||||
const char *const type,
|
||||
void *const userdata);
|
||||
void xmpp_handler_delete(xmpp_conn_t *const conn, xmpp_handler handler);
|
||||
const char *ns,
|
||||
const char *name,
|
||||
const char *type,
|
||||
void *userdata);
|
||||
void xmpp_handler_delete(xmpp_conn_t *conn, xmpp_handler handler);
|
||||
|
||||
void xmpp_id_handler_add(xmpp_conn_t *const conn,
|
||||
void xmpp_id_handler_add(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const id,
|
||||
void *const userdata);
|
||||
void xmpp_id_handler_delete(xmpp_conn_t *const conn,
|
||||
const char *id,
|
||||
void *userdata);
|
||||
void xmpp_id_handler_delete(xmpp_conn_t *conn,
|
||||
xmpp_handler handler,
|
||||
const char *const id);
|
||||
const char *id);
|
||||
|
||||
/*
|
||||
void xmpp_register_stanza_handler(conn, stanza, xmlns, type, handler)
|
||||
@@ -337,94 +332,88 @@ xmpp_stanza_t *xmpp_stanza_new(xmpp_ctx_t *ctx);
|
||||
xmpp_stanza_t *xmpp_stanza_new_from_string(xmpp_ctx_t *ctx, const char *str);
|
||||
|
||||
/* clone a stanza */
|
||||
xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t *const stanza);
|
||||
xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t *stanza);
|
||||
|
||||
/* copies a stanza and all children */
|
||||
xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t *const stanza);
|
||||
xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t *stanza);
|
||||
|
||||
/* free a stanza object and it's contents */
|
||||
int xmpp_stanza_release(xmpp_stanza_t *const stanza);
|
||||
int xmpp_stanza_release(xmpp_stanza_t *stanza);
|
||||
|
||||
xmpp_ctx_t *xmpp_stanza_get_context(const xmpp_stanza_t *const stanza);
|
||||
xmpp_ctx_t *xmpp_stanza_get_context(const xmpp_stanza_t *stanza);
|
||||
|
||||
int xmpp_stanza_is_text(xmpp_stanza_t *const stanza);
|
||||
int xmpp_stanza_is_tag(xmpp_stanza_t *const stanza);
|
||||
int xmpp_stanza_is_text(xmpp_stanza_t *stanza);
|
||||
int xmpp_stanza_is_tag(xmpp_stanza_t *stanza);
|
||||
|
||||
/* marshall a stanza into text for transmission or display */
|
||||
int xmpp_stanza_to_text(xmpp_stanza_t *stanza,
|
||||
char **const buf,
|
||||
size_t *const buflen);
|
||||
int xmpp_stanza_to_text(xmpp_stanza_t *stanza, char **buf, size_t *buflen);
|
||||
|
||||
xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t *const stanza);
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t *const stanza,
|
||||
const char *const name);
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t *const stanza,
|
||||
const char *const ns);
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name_and_ns(xmpp_stanza_t *const stanza,
|
||||
const char *const name,
|
||||
const char *const ns);
|
||||
xmpp_stanza_t *xmpp_stanza_get_next(xmpp_stanza_t *const stanza);
|
||||
xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t *stanza);
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t *stanza,
|
||||
const char *name);
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t *stanza,
|
||||
const char *ns);
|
||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name_and_ns(xmpp_stanza_t *stanza,
|
||||
const char *name,
|
||||
const char *ns);
|
||||
xmpp_stanza_t *xmpp_stanza_get_next(xmpp_stanza_t *stanza);
|
||||
int xmpp_stanza_add_child(xmpp_stanza_t *stanza, xmpp_stanza_t *child);
|
||||
int xmpp_stanza_add_child_ex(xmpp_stanza_t *stanza,
|
||||
xmpp_stanza_t *child,
|
||||
int do_clone);
|
||||
|
||||
const char *xmpp_stanza_get_attribute(xmpp_stanza_t *const stanza,
|
||||
const char *const name);
|
||||
int xmpp_stanza_get_attribute_count(xmpp_stanza_t *const stanza);
|
||||
int xmpp_stanza_get_attributes(xmpp_stanza_t *const stanza,
|
||||
const char *xmpp_stanza_get_attribute(xmpp_stanza_t *stanza, const char *name);
|
||||
int xmpp_stanza_get_attribute_count(xmpp_stanza_t *stanza);
|
||||
int xmpp_stanza_get_attributes(xmpp_stanza_t *stanza,
|
||||
const char **attr,
|
||||
int attrlen);
|
||||
/* concatenate all child text nodes. this function
|
||||
* returns a string that must be freed by the caller */
|
||||
char *xmpp_stanza_get_text(xmpp_stanza_t *const stanza);
|
||||
const char *xmpp_stanza_get_text_ptr(xmpp_stanza_t *const stanza);
|
||||
const char *xmpp_stanza_get_name(xmpp_stanza_t *const stanza);
|
||||
char *xmpp_stanza_get_text(xmpp_stanza_t *stanza);
|
||||
const char *xmpp_stanza_get_text_ptr(xmpp_stanza_t *stanza);
|
||||
const char *xmpp_stanza_get_name(xmpp_stanza_t *stanza);
|
||||
/* set_attribute adds/replaces attributes */
|
||||
int xmpp_stanza_set_attribute(xmpp_stanza_t *const stanza,
|
||||
const char *const key,
|
||||
const char *const value);
|
||||
int xmpp_stanza_set_name(xmpp_stanza_t *stanza, const char *const name);
|
||||
int xmpp_stanza_set_text(xmpp_stanza_t *stanza, const char *const text);
|
||||
int xmpp_stanza_set_attribute(xmpp_stanza_t *stanza,
|
||||
const char *key,
|
||||
const char *value);
|
||||
int xmpp_stanza_set_name(xmpp_stanza_t *stanza, const char *name);
|
||||
int xmpp_stanza_set_text(xmpp_stanza_t *stanza, const char *text);
|
||||
int xmpp_stanza_set_text_with_size(xmpp_stanza_t *stanza,
|
||||
const char *const text,
|
||||
const size_t size);
|
||||
int xmpp_stanza_del_attribute(xmpp_stanza_t *const stanza,
|
||||
const char *const name);
|
||||
const char *text,
|
||||
size_t size);
|
||||
int xmpp_stanza_del_attribute(xmpp_stanza_t *stanza, const char *name);
|
||||
|
||||
/* common stanza helpers */
|
||||
const char *xmpp_stanza_get_ns(xmpp_stanza_t *const stanza);
|
||||
const char *xmpp_stanza_get_type(xmpp_stanza_t *const stanza);
|
||||
const char *xmpp_stanza_get_id(xmpp_stanza_t *const stanza);
|
||||
const char *xmpp_stanza_get_to(xmpp_stanza_t *const stanza);
|
||||
const char *xmpp_stanza_get_from(xmpp_stanza_t *const stanza);
|
||||
int xmpp_stanza_set_ns(xmpp_stanza_t *const stanza, const char *const ns);
|
||||
int xmpp_stanza_set_id(xmpp_stanza_t *const stanza, const char *const id);
|
||||
int xmpp_stanza_set_type(xmpp_stanza_t *const stanza, const char *const type);
|
||||
int xmpp_stanza_set_to(xmpp_stanza_t *const stanza, const char *const to);
|
||||
int xmpp_stanza_set_from(xmpp_stanza_t *const stanza, const char *const from);
|
||||
const char *xmpp_stanza_get_ns(xmpp_stanza_t *stanza);
|
||||
const char *xmpp_stanza_get_type(xmpp_stanza_t *stanza);
|
||||
const char *xmpp_stanza_get_id(xmpp_stanza_t *stanza);
|
||||
const char *xmpp_stanza_get_to(xmpp_stanza_t *stanza);
|
||||
const char *xmpp_stanza_get_from(xmpp_stanza_t *stanza);
|
||||
int xmpp_stanza_set_ns(xmpp_stanza_t *stanza, const char *ns);
|
||||
int xmpp_stanza_set_id(xmpp_stanza_t *stanza, const char *id);
|
||||
int xmpp_stanza_set_type(xmpp_stanza_t *stanza, const char *type);
|
||||
int xmpp_stanza_set_to(xmpp_stanza_t *stanza, const char *to);
|
||||
int xmpp_stanza_set_from(xmpp_stanza_t *stanza, const char *from);
|
||||
|
||||
/* allocate and initialize a stanza in reply to another */
|
||||
xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t *const stanza);
|
||||
xmpp_stanza_t *xmpp_stanza_reply_error(xmpp_stanza_t *const stanza,
|
||||
const char *const error_type,
|
||||
const char *const condition,
|
||||
const char *const text);
|
||||
xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t *stanza);
|
||||
xmpp_stanza_t *xmpp_stanza_reply_error(xmpp_stanza_t *stanza,
|
||||
const char *error_type,
|
||||
const char *condition,
|
||||
const char *text);
|
||||
|
||||
/* stanza subclasses */
|
||||
xmpp_stanza_t *xmpp_message_new(xmpp_ctx_t *ctx,
|
||||
const char *const type,
|
||||
const char *const to,
|
||||
const char *const id);
|
||||
const char *type,
|
||||
const char *to,
|
||||
const char *id);
|
||||
char *xmpp_message_get_body(xmpp_stanza_t *msg);
|
||||
int xmpp_message_set_body(xmpp_stanza_t *msg, const char *const text);
|
||||
int xmpp_message_set_body(xmpp_stanza_t *msg, const char *text);
|
||||
|
||||
xmpp_stanza_t *
|
||||
xmpp_iq_new(xmpp_ctx_t *ctx, const char *const type, const char *const id);
|
||||
xmpp_stanza_t *xmpp_iq_new(xmpp_ctx_t *ctx, const char *type, const char *id);
|
||||
xmpp_stanza_t *xmpp_presence_new(xmpp_ctx_t *ctx);
|
||||
xmpp_stanza_t *xmpp_error_new(xmpp_ctx_t *ctx,
|
||||
xmpp_error_type_t const type,
|
||||
const char *const text);
|
||||
xmpp_stanza_t *
|
||||
xmpp_error_new(xmpp_ctx_t *ctx, xmpp_error_type_t type, const char *text);
|
||||
|
||||
/* jid */
|
||||
|
||||
@@ -440,10 +429,10 @@ char *xmpp_jid_resource(xmpp_ctx_t *ctx, const char *jid);
|
||||
|
||||
/* event loop */
|
||||
|
||||
void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout);
|
||||
void xmpp_run_once(xmpp_ctx_t *ctx, unsigned long timeout);
|
||||
void xmpp_run(xmpp_ctx_t *ctx);
|
||||
void xmpp_stop(xmpp_ctx_t *ctx);
|
||||
void xmpp_ctx_set_timeout(xmpp_ctx_t *const ctx, const unsigned long timeout);
|
||||
void xmpp_ctx_set_timeout(xmpp_ctx_t *ctx, unsigned long timeout);
|
||||
|
||||
/* UUID */
|
||||
|
||||
|
||||
16
tests/cert.pem
Normal file
16
tests/cert.pem
Normal file
@@ -0,0 +1,16 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICfjCCAjSgAwIBAgIIW5u5Vwn2Mv0wCgYIKoZIzj0EAwIwSzFJMEcGA1UEAwxA
|
||||
dmVyeS5sb25nLnVzZXJuYW1lQHNvLnRoZS5hc24xLmxlbmd0aC5pcy5hLnZhbGlk
|
||||
LmFzY2lpLmNoYXJhY3RlcjAgFw0yMTAzMDExOTExMDBaGA8yMTIxMDMwMTE5MTEw
|
||||
MFowSzFJMEcGA1UEAwxAdmVyeS5sb25nLnVzZXJuYW1lQHNvLnRoZS5hc24xLmxl
|
||||
bmd0aC5pcy5hLnZhbGlkLmFzY2lpLmNoYXJhY3RlcjBJMBMGByqGSM49AgEGCCqG
|
||||
SM49AwEBAzIABI/tSR5cZ9iHCVw0JwmKLvV3TbxPg3kDdouB0R2WKEdEWwXMIHkE
|
||||
85RReISg+9/JDaOCAQ4wggEKMAkGA1UdEwQCMAAwHQYDVR0OBBYEFPjLGyHxqlOV
|
||||
nXJQ9YBrnureO8LiMB8GA1UdIwQYMBaAFPjLGyHxqlOVnXJQ9YBrnureO8LiMAsG
|
||||
A1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAjCBmgYDVR0RBIGSMIGPoE4G
|
||||
CCsGAQUFBwgFoEIMQHZlcnkubG9uZy51c2VybmFtZUBzby50aGUuYXNuMS5sZW5n
|
||||
dGguaXMuYS52YWxpZC5hc2NpaS5jaGFyYWN0ZXKBDnlldEBub3RoZXIuc2Fugg53
|
||||
d3cuc3Ryb3BoZS5pbaAdBggrBgEFBQcIBaARDA9zZWNvbmRAeG1wcC5qaWQwCgYI
|
||||
KoZIzj0EAwIDOAAwNQIZAJmfqBhBMdaKCiWEuXu84K4+lznfzlRfmwIYCGRD1xk0
|
||||
9cRa3V6PVwYWz6HcdRdMUBUj
|
||||
-----END CERTIFICATE-----
|
||||
5
tests/key.pem
Normal file
5
tests/key.pem
Normal file
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MF8CAQEEGF7SsbTSOjzb97nFc7Qbt4sic+1nZk+ETqAKBggqhkjOPQMBAaE0AzIA
|
||||
BI/tSR5cZ9iHCVw0JwmKLvV3TbxPg3kDdouB0R2WKEdEWwXMIHkE85RReISg+9/J
|
||||
DQ==
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
static uint8_t char_to_bin(char c)
|
||||
{
|
||||
return c <= '9'
|
||||
? (uint8_t)(c - '0')
|
||||
: c <= 'Z' ? (uint8_t)(c - 'A' + 10) : (uint8_t)(c - 'a' + 10);
|
||||
return c <= '9' ? (uint8_t)(c - '0')
|
||||
: c <= 'Z' ? (uint8_t)(c - 'A' + 10)
|
||||
: (uint8_t)(c - 'a' + 10);
|
||||
}
|
||||
|
||||
void test_hex_to_bin(const char *hex, uint8_t *bin, size_t *bin_len)
|
||||
|
||||
28
tests/test.h
28
tests/test.h
@@ -33,17 +33,17 @@
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#endif
|
||||
|
||||
#define COMPARE(v1, v2) \
|
||||
do { \
|
||||
const char *__v1 = v1; \
|
||||
const char *__v2 = v2; \
|
||||
if (strcmp(__v1, __v2) != 0) { \
|
||||
printf("%s differs!\n" \
|
||||
"expected: %s\n" \
|
||||
"got: %s\n", \
|
||||
#v1, __v1, __v2); \
|
||||
exit(1); \
|
||||
} \
|
||||
#define COMPARE(v1, v2) \
|
||||
do { \
|
||||
const char *__v1 = v1; \
|
||||
const char *__v2 = v2; \
|
||||
if (strcmp(__v1, __v2) != 0) { \
|
||||
printf("Error: %s\n" \
|
||||
"Expected: %s\n" \
|
||||
"Got: %s\n", \
|
||||
#v1 " != " #v2, __v1, __v2); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define COMPARE_BUF(v1, len1, v2, len2) \
|
||||
@@ -53,9 +53,9 @@
|
||||
size_t __len1 = len1; \
|
||||
size_t __len2 = len2; \
|
||||
if (__len1 != __len2 || memcmp(__v1, __v2, __len1) != 0) { \
|
||||
printf("%s differs!\n", #v1); \
|
||||
printf("expected: 0x%s\n", test_bin_to_hex(__v1, __len1)); \
|
||||
printf("got: 0x%s\n", test_bin_to_hex(__v2, __len2)); \
|
||||
printf("Error: %s\n", #v1 " != " #v2); \
|
||||
printf("Expected: 0x%s\n", test_bin_to_hex(__v1, __len1)); \
|
||||
printf("Got: 0x%s\n", test_bin_to_hex(__v2, __len2)); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -22,7 +22,7 @@ static int mem_alloc_called = 0;
|
||||
static int mem_free_called = 0;
|
||||
static int mem_realloc_called = 0;
|
||||
|
||||
void *my_alloc(const size_t size, void *const userdata)
|
||||
void *my_alloc(size_t size, void *userdata)
|
||||
{
|
||||
(void)userdata;
|
||||
|
||||
@@ -30,7 +30,7 @@ void *my_alloc(const size_t size, void *const userdata)
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void my_free(void *p, void *const userdata)
|
||||
void my_free(void *p, void *userdata)
|
||||
{
|
||||
(void)userdata;
|
||||
|
||||
@@ -38,7 +38,7 @@ void my_free(void *p, void *const userdata)
|
||||
return free(p);
|
||||
}
|
||||
|
||||
void *my_realloc(void *p, const size_t size, void *const userdata)
|
||||
void *my_realloc(void *p, size_t size, void *userdata)
|
||||
{
|
||||
(void)userdata;
|
||||
|
||||
@@ -46,10 +46,10 @@ void *my_realloc(void *p, const size_t size, void *const userdata)
|
||||
return realloc(p, size);
|
||||
}
|
||||
|
||||
void my_logger(void *const userdata,
|
||||
const xmpp_log_level_t level,
|
||||
const char *const area,
|
||||
const char *const msg)
|
||||
void my_logger(void *userdata,
|
||||
xmpp_log_level_t level,
|
||||
const char *area,
|
||||
const char *msg)
|
||||
{
|
||||
if (strcmp((char *)userdata, "asdf") == 0 && level == XMPP_LEVEL_DEBUG &&
|
||||
strcmp(area, "test") == 0 && strcmp(msg, "hello") == 0)
|
||||
|
||||
@@ -21,19 +21,20 @@
|
||||
#include "rand.c"
|
||||
|
||||
/* stubs to build test without whole libstrophe */
|
||||
void *xmpp_alloc(const xmpp_ctx_t *const ctx, const size_t size)
|
||||
void *xmpp_alloc(const xmpp_ctx_t *ctx, size_t size)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)size;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xmpp_free(const xmpp_ctx_t *const ctx, void *p)
|
||||
void xmpp_free(const xmpp_ctx_t *ctx, void *p)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)p;
|
||||
}
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
int xmpp_snprintf(char *str, size_t count, const char *fmt, ...)
|
||||
{
|
||||
(void)str;
|
||||
@@ -41,6 +42,7 @@ int xmpp_snprintf(char *str, size_t count, const char *fmt, ...)
|
||||
(void)fmt;
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_SNPRINTF */
|
||||
|
||||
uint64_t time_stamp(void)
|
||||
{
|
||||
|
||||
69
tests/test_xmppaddr.c
Normal file
69
tests/test_xmppaddr.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/* test_xmppaddr.c
|
||||
** libstrophe XMPP client library -- test routines for the xmppaddr
|
||||
** certificate API's
|
||||
**
|
||||
** Copyright (C) 2021 Steffen Jaeckel
|
||||
**
|
||||
** This software is provided AS-IS with no warranty, either express
|
||||
** or implied.
|
||||
**
|
||||
** This program is dual licensed under the MIT and GPLv3 licenses.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "strophe.h"
|
||||
|
||||
#include "test.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
xmpp_ctx_t *ctx;
|
||||
xmpp_conn_t *conn;
|
||||
xmpp_log_t *log;
|
||||
|
||||
char xmppaddr_num[] = "0";
|
||||
unsigned int n;
|
||||
|
||||
xmpp_initialize();
|
||||
log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);
|
||||
ctx = xmpp_ctx_new(NULL, log);
|
||||
conn = xmpp_conn_new(ctx);
|
||||
|
||||
xmpp_conn_set_client_cert(conn, "tests/cert.pem", "tests/key.pem");
|
||||
|
||||
xmppaddr_num[0] = xmppaddr_num[0] + xmpp_conn_cert_xmppaddr_num(conn);
|
||||
|
||||
COMPARE("2", xmppaddr_num);
|
||||
|
||||
for (n = 0; n < 3; ++n) {
|
||||
char *r = xmpp_conn_cert_xmppaddr(conn, n);
|
||||
switch (n) {
|
||||
case 0:
|
||||
COMPARE("very.long.username@so.the.asn1.length.is.a.valid.ascii."
|
||||
"character",
|
||||
r);
|
||||
break;
|
||||
case 1:
|
||||
COMPARE("second@xmpp.jid", r);
|
||||
break;
|
||||
default:
|
||||
if (r != NULL) {
|
||||
printf("\nThere shall only be two id-on-xmppAddr SANs!\nFound "
|
||||
"another one: %s\n",
|
||||
r);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
free(r);
|
||||
}
|
||||
|
||||
xmpp_conn_release(conn);
|
||||
xmpp_ctx_free(ctx);
|
||||
xmpp_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user