diff options
-rw-r--r-- | src/rexmpp.c | 4 | ||||
-rw-r--r-- | src/rexmpp.h | 10 | ||||
-rw-r--r-- | src/rexmpp_dns.c | 41 | ||||
-rw-r--r-- | src/rexmpp_dns.h | 20 | ||||
-rw-r--r-- | src/rexmpp_jingle.c | 49 | ||||
-rw-r--r-- | src/rexmpp_jingle.h | 1 | ||||
-rw-r--r-- | src/rexmpp_sasl.c | 81 | ||||
-rw-r--r-- | src/rexmpp_tls.c | 173 | ||||
-rw-r--r-- | src/rexmpp_tls.h | 1 |
9 files changed, 203 insertions, 177 deletions
diff --git a/src/rexmpp.c b/src/rexmpp.c index 7eede3f..a119d1f 100644 --- a/src/rexmpp.c +++ b/src/rexmpp.c @@ -670,6 +670,8 @@ rexmpp_err_t rexmpp_init (rexmpp_t *s, xmlFreeParserCtxt(s->xml_parser); return REXMPP_E_PGP; } +#else + s->pgp_ctx = NULL; #endif #ifdef HAVE_CURL if (curl_global_init(CURL_GLOBAL_ALL) != 0) { @@ -680,6 +682,8 @@ rexmpp_err_t rexmpp_init (rexmpp_t *s, rexmpp_log(s, LOG_CRIT, "Failed to initialize curl_multi"); /* todo: free other structures and fail */ } +#else + s->curl_multi = NULL; #endif return REXMPP_SUCCESS; diff --git a/src/rexmpp.h b/src/rexmpp.h index 94f2df2..dec03dc 100644 --- a/src/rexmpp.h +++ b/src/rexmpp.h @@ -318,7 +318,7 @@ struct rexmpp rexmpp_xml_t *iq_cache; /* Jingle context. */ - rexmpp_jingle_ctx_t jingle; + rexmpp_jingle_ctx_t *jingle; /* Connection and stream management. */ unsigned int reconnect_number; @@ -377,19 +377,23 @@ struct rexmpp xmlNodePtr input_queue_last; /* TLS structures. */ - rexmpp_tls_t tls; + rexmpp_tls_t *tls; /* SASL structures. */ - rexmpp_sasl_ctx_t sasl; + rexmpp_sasl_ctx_t *sasl; /* OpenPGP structures */ #ifdef HAVE_GPGME gpgme_ctx_t pgp_ctx; +#else + void *pgp_ctx; #endif /* curl structures */ #ifdef HAVE_CURL CURLM *curl_multi; +#else + void *curl_multi; #endif }; diff --git a/src/rexmpp_dns.c b/src/rexmpp_dns.c index 1894481..8c40c0a 100644 --- a/src/rexmpp_dns.c +++ b/src/rexmpp_dns.c @@ -102,22 +102,22 @@ rexmpp_dns_result_t *result_from_hostent (struct hostent *hostinfo) { int rexmpp_dns_ctx_init (rexmpp_t *s) { #if defined(USE_UNBOUND) int err; - s->resolver.ctx = ub_ctx_create(); - if (s->resolver.ctx == NULL) { + s->resolver = ub_ctx_create(); + if (s->resolver == NULL) { rexmpp_log(s, LOG_CRIT, "Failed to create resolver context"); return 1; } - err = ub_ctx_resolvconf(s->resolver.ctx, NULL); + err = ub_ctx_resolvconf(s->resolver, NULL); if (err != 0) { rexmpp_log(s, LOG_WARNING, "Failed to read resolv.conf: %s", ub_strerror(err)); } - err = ub_ctx_hosts(s->resolver.ctx, NULL); + err = ub_ctx_hosts(s->resolver, NULL); if (err != 0) { rexmpp_log(s, LOG_WARNING, "Failed to read hosts file: %s", ub_strerror(err)); } - err = ub_ctx_add_ta_file(s->resolver.ctx, DNSSEC_TRUST_ANCHOR_FILE); + err = ub_ctx_add_ta_file(s->resolver, DNSSEC_TRUST_ANCHOR_FILE); if (err != 0) { rexmpp_log(s, LOG_WARNING, "Failed to set root key file for DNSSEC: %s", ub_strerror(err)); @@ -130,7 +130,7 @@ int rexmpp_dns_ctx_init (rexmpp_t *s) { ares_strerror(err)); return 1; } - err = ares_init(&(s->resolver.channel)); + err = ares_init(&(s->resolver)); if (err) { rexmpp_log(s, LOG_CRIT, "ares channel initialisation error: %s", ares_strerror(err)); @@ -139,7 +139,7 @@ int rexmpp_dns_ctx_init (rexmpp_t *s) { } return 0; #else - (void)s; + s->resolver = NULL; return 0; #endif } @@ -151,12 +151,15 @@ void rexmpp_dns_ctx_cleanup (rexmpp_t *s) { void rexmpp_dns_ctx_deinit (rexmpp_t *s) { #if defined(USE_UNBOUND) - if (s->resolver.ctx != NULL) { - ub_ctx_delete(s->resolver.ctx); - s->resolver.ctx = NULL; + if (s->resolver != NULL) { + ub_ctx_delete(s->resolver); + s->resolver = NULL; } #elif defined(USE_CARES) - ares_destroy(s->resolver.channel); + if (s->resolver != NULL) { + ares_destroy(s->resolver); + s->resolver = NULL; + } ares_library_cleanup(); #else (void)s; @@ -166,13 +169,13 @@ void rexmpp_dns_ctx_deinit (rexmpp_t *s) { int rexmpp_dns_fds (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) { #if defined(USE_UNBOUND) (void)write_fds; - int max_fd = ub_fd(s->resolver.ctx) + 1; + int max_fd = ub_fd(s->resolver) + 1; if (max_fd != 0) { FD_SET(max_fd - 1, read_fds); } return max_fd; #elif defined(USE_CARES) - return ares_fds(s->resolver.channel, read_fds, write_fds); + return ares_fds(s->resolver, read_fds, write_fds); #else (void)s; (void)read_fds; @@ -197,7 +200,7 @@ struct timespec * rexmpp_dns_timeout (rexmpp_t *s, tv_ms.tv_sec = tv->tv_sec; tv_ms.tv_usec = tv->tv_nsec / 1000; } - struct timeval *ret_ms = ares_timeout(s->resolver.channel, max_tv_ms, &tv_ms); + struct timeval *ret_ms = ares_timeout(s->resolver, max_tv_ms, &tv_ms); if (ret_ms == max_tv_ms) { return max_tv; } else { @@ -349,7 +352,7 @@ int rexmpp_dns_resolve (rexmpp_t *s, d->s = s; d->cb = callback; d->ptr = ptr; - int err = ub_resolve_async(s->resolver.ctx, query, rrtype, rrclass, + int err = ub_resolve_async(s->resolver, query, rrtype, rrclass, d, rexmpp_dns_cb, NULL); if (err) { rexmpp_log(s, LOG_ERR, "Failed to query %s: %s", @@ -362,7 +365,7 @@ int rexmpp_dns_resolve (rexmpp_t *s, d->s = s; d->cb = callback; d->ptr = ptr; - ares_query(s->resolver.channel, query, rrclass, rrtype, rexmpp_dns_cb, d); + ares_query(s->resolver, query, rrclass, rrtype, rexmpp_dns_cb, d); #else if (rrclass == 1) { if (rrtype == 1 || rrtype == 28) { @@ -395,8 +398,8 @@ int rexmpp_dns_process (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) { #if defined(USE_UNBOUND) (void)read_fds; (void)write_fds; - if (ub_poll(s->resolver.ctx)) { - int err = ub_process(s->resolver.ctx); + if (ub_poll(s->resolver)) { + int err = ub_process(s->resolver); if (err != 0) { rexmpp_log(s, LOG_ERR, "DNS query processing error: %s", ub_strerror(err)); @@ -405,7 +408,7 @@ int rexmpp_dns_process (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) { } return 0; #elif defined(USE_CARES) - ares_process(s->resolver.channel, read_fds, write_fds); + ares_process(s->resolver, read_fds, write_fds); return 0; #else (void)s; diff --git a/src/rexmpp_dns.h b/src/rexmpp_dns.h index abfe6b7..06aea8a 100644 --- a/src/rexmpp_dns.h +++ b/src/rexmpp_dns.h @@ -21,21 +21,21 @@ */ #if defined(USE_UNBOUND) #include <unbound.h> -struct rexmpp_dns_ctx { - struct ub_ctx *ctx; -}; +typedef struct ub_ctx* rexmpp_dns_ctx_t; +/* struct rexmpp_dns_ctx { */ +/* struct ub_ctx *ctx; */ +/* }; */ #elif defined(USE_CARES) #include <ares.h> -struct rexmpp_dns_ctx { - ares_channel channel; -}; +typedef ares_channel rexmpp_dns_ctx_t; +/* struct rexmpp_dns_ctx { */ +/* ares_channel channel; */ +/* }; */ #else -struct rexmpp_dns_ctx { - int dummy; -}; +typedef void* rexmpp_dns_ctx_t; #endif -typedef struct rexmpp_dns_ctx rexmpp_dns_ctx_t; +/* typedef struct rexmpp_dns_ctx rexmpp_dns_ctx_t; */ struct rexmpp_dns_srv { uint16_t priority; diff --git a/src/rexmpp_jingle.c b/src/rexmpp_jingle.c index 11393c0..c91c35d 100644 --- a/src/rexmpp_jingle.c +++ b/src/rexmpp_jingle.c @@ -53,7 +53,7 @@ rexmpp_jingle_session_by_id (rexmpp_t *s, const char *sid) { if (sid == NULL) { return NULL; } - rexmpp_jingle_session_t *cur = s->jingle.sessions; + rexmpp_jingle_session_t *cur = s->jingle->sessions; while (cur != NULL) { if (strcmp(cur->sid, sid) == 0) { return cur; @@ -136,11 +136,11 @@ void rexmpp_jingle_session_delete (rexmpp_t *s, rexmpp_jingle_session_t *sess) { return; } rexmpp_log(s, LOG_DEBUG, "Removing Jingle session %s", sess->sid); - rexmpp_jingle_session_t *cur = s->jingle.sessions, *prev = NULL; + rexmpp_jingle_session_t *cur = s->jingle->sessions, *prev = NULL; while (cur != NULL) { if (sess == cur) { if (prev == NULL) { - s->jingle.sessions = cur->next; + s->jingle->sessions = cur->next; } else { prev->next = cur->next; } @@ -158,7 +158,7 @@ void rexmpp_jingle_session_delete_by_id (rexmpp_t *s, const char *sid) { int rexmpp_jingle_session_add (rexmpp_t *s, rexmpp_jingle_session_t *sess) { uint32_t sessions_num = 0; - rexmpp_jingle_session_t *cur = s->jingle.sessions; + rexmpp_jingle_session_t *cur = s->jingle->sessions; while (cur != NULL) { sessions_num++; cur = cur->next; @@ -169,8 +169,8 @@ int rexmpp_jingle_session_add (rexmpp_t *s, rexmpp_jingle_session_t *sess) { return 0; } rexmpp_log(s, LOG_DEBUG, "Adding Jingle session %s", sess->sid); - sess->next = s->jingle.sessions; - s->jingle.sessions = sess; + sess->next = s->jingle->sessions; + s->jingle->sessions = sess; return 1; } @@ -231,7 +231,7 @@ rexmpp_jingle_session_by_ibb_sid (rexmpp_t *s, const char *ibb_sid) { if (ibb_sid == NULL) { return NULL; } - rexmpp_jingle_session_t *cur = s->jingle.sessions; + rexmpp_jingle_session_t *cur = s->jingle->sessions; while (cur != NULL) { if (cur->type == REXMPP_JINGLE_SESSION_FILE && strcmp(cur->ibb_sid, ibb_sid) == 0) { @@ -245,24 +245,27 @@ rexmpp_jingle_session_by_ibb_sid (rexmpp_t *s, const char *ibb_sid) { } int rexmpp_jingle_init (rexmpp_t *s) { - s->jingle.sessions = NULL; + s->jingle = malloc(sizeof(struct rexmpp_jingle_ctx)); + s->jingle->sessions = NULL; #ifdef ENABLE_CALLS g_networking_init(); srtp_init(); - s->jingle.gloop = g_main_loop_new(NULL, FALSE); + s->jingle->gloop = g_main_loop_new(NULL, FALSE); #endif return 0; } void rexmpp_jingle_stop (rexmpp_t *s) { - while (s->jingle.sessions != NULL) { - rexmpp_jingle_session_delete(s, s->jingle.sessions); + while (s->jingle->sessions != NULL) { + rexmpp_jingle_session_delete(s, s->jingle->sessions); } #ifdef ENABLE_CALLS - g_main_loop_quit(s->jingle.gloop); - s->jingle.gloop = NULL; + g_main_loop_quit(s->jingle->gloop); + s->jingle->gloop = NULL; srtp_shutdown(); #endif + free(s->jingle); + s->jingle = NULL; } @@ -740,7 +743,7 @@ rexmpp_jingle_candidate_gathering_done_cb (NiceAgent *agent, int cert_list_size = 0; /* We'll need a certificate a bit later, but checking it before allocating other things. */ - int err = gnutls_certificate_get_x509_crt(sess->s->jingle.dtls_cred, 0, + int err = gnutls_certificate_get_x509_crt(sess->s->tls->dtls_cred, 0, &cert_list, &cert_list_size); if (err) { rexmpp_log(sess->s, LOG_ERR, @@ -1112,7 +1115,7 @@ rexmpp_jingle_component_state_changed_cb (NiceAgent *agent, } gnutls_set_default_priority(*tls_session); gnutls_credentials_set(*tls_session, GNUTLS_CRD_CERTIFICATE, - sess->s->jingle.dtls_cred); + sess->s->tls->dtls_cred); gnutls_transport_set_ptr(*tls_session, &sess->component[component_id - 1]); gnutls_transport_set_push_function(*tls_session, rexmpp_jingle_dtls_push_func); @@ -1197,7 +1200,7 @@ rexmpp_jingle_ice_recv_cb (NiceAgent *agent, guint stream_id, guint component_id int rexmpp_jingle_ice_agent_init (rexmpp_jingle_session_t *sess) { - sess->ice_agent = nice_agent_new(g_main_loop_get_context (sess->s->jingle.gloop), + sess->ice_agent = nice_agent_new(g_main_loop_get_context (sess->s->jingle->gloop), NICE_COMPATIBILITY_RFC5245); if (sess->s->local_address != NULL) { NiceAddress *address = nice_address_new(); @@ -1222,7 +1225,7 @@ rexmpp_jingle_ice_agent_init (rexmpp_jingle_session_t *sess) int i; for (i = 0; i < (sess->rtcp_mux ? 1 : 2); i++) { nice_agent_attach_recv(sess->ice_agent, sess->ice_stream_id, i + 1, - g_main_loop_get_context (sess->s->jingle.gloop), + g_main_loop_get_context (sess->s->jingle->gloop), rexmpp_jingle_ice_recv_cb, &sess->component[i]); } @@ -1691,7 +1694,7 @@ int rexmpp_jingle_fds(rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) { #ifdef ENABLE_CALLS gint poll_timeout; GPollFD poll_fds[10]; - GMainContext* gctx = g_main_loop_get_context(s->jingle.gloop); + GMainContext* gctx = g_main_loop_get_context(s->jingle->gloop); if (g_main_context_acquire(gctx)) { gint poll_fds_n = g_main_context_query(gctx, G_PRIORITY_HIGH, @@ -1713,7 +1716,7 @@ int rexmpp_jingle_fds(rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) { } rexmpp_jingle_session_t *sess; - for (sess = s->jingle.sessions; sess != NULL; sess = sess->next) { + for (sess = s->jingle->sessions; sess != NULL; sess = sess->next) { for (i = 0; i < 2; i++) { if (sess->component[i].dtls_state != REXMPP_TLS_INACTIVE && sess->component[i].dtls_state != REXMPP_TLS_CLOSED && @@ -1757,7 +1760,7 @@ struct timespec * rexmpp_jingle_timeout (rexmpp_t *s, #ifdef ENABLE_CALLS gint poll_timeout; GPollFD poll_fds[10]; - GMainContext* gctx = g_main_loop_get_context(s->jingle.gloop); + GMainContext* gctx = g_main_loop_get_context(s->jingle->gloop); if (g_main_context_acquire(gctx)) { g_main_context_query(gctx, G_PRIORITY_HIGH, @@ -1767,7 +1770,7 @@ struct timespec * rexmpp_jingle_timeout (rexmpp_t *s, g_main_context_release(gctx); rexmpp_jingle_session_t *sess; - for (sess = s->jingle.sessions; sess != NULL; sess = sess->next) { + for (sess = s->jingle->sessions; sess != NULL; sess = sess->next) { int i; for (i = 0; i < 2; i++) { if (sess->component[i].dtls_state != REXMPP_TLS_INACTIVE && @@ -1817,7 +1820,7 @@ rexmpp_jingle_run (rexmpp_t *s, gnutls_datum_t client_key, client_salt, server_key, server_salt; char client_sess_key[SRTP_AES_ICM_128_KEY_LEN_WSALT * 2], server_sess_key[SRTP_AES_ICM_128_KEY_LEN_WSALT * 2]; - for (sess = s->jingle.sessions; sess != NULL; sess = sess->next) { + for (sess = s->jingle->sessions; sess != NULL; sess = sess->next) { char input[4096 + SRTP_MAX_TRAILER_LEN]; int input_len; int comp_id; @@ -2030,7 +2033,7 @@ rexmpp_jingle_run (rexmpp_t *s, } } } - g_main_context_iteration(g_main_loop_get_context(s->jingle.gloop), 0); + g_main_context_iteration(g_main_loop_get_context(s->jingle->gloop), 0); #else (void)s; (void)read_fds; diff --git a/src/rexmpp_jingle.h b/src/rexmpp_jingle.h index eb0a0d3..afe5d86 100644 --- a/src/rexmpp_jingle.h +++ b/src/rexmpp_jingle.h @@ -113,7 +113,6 @@ struct rexmpp_jingle_session { struct rexmpp_jingle_ctx { #ifdef ENABLE_CALLS GMainLoop* gloop; - gnutls_certificate_credentials_t dtls_cred; #endif rexmpp_jingle_session_t *sessions; }; diff --git a/src/rexmpp_sasl.c b/src/rexmpp_sasl.c index 7dd16ba..cf5d1fe 100644 --- a/src/rexmpp_sasl.c +++ b/src/rexmpp_sasl.c @@ -31,28 +31,33 @@ int rexmpp_sasl_cb (Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop) { } int rexmpp_sasl_ctx_init (rexmpp_t *s) { - int err = gsasl_init(&(s->sasl.ctx)); + s->sasl = malloc(sizeof(struct rexmpp_sasl_ctx)); + int err = gsasl_init(&(s->sasl->ctx)); if (err != GSASL_OK) { rexmpp_log(s, LOG_CRIT, "gsasl initialisation error: %s", gsasl_strerror(err)); return -1; } - gsasl_callback_hook_set(s->sasl.ctx, s); - gsasl_callback_set(s->sasl.ctx, rexmpp_sasl_cb); + gsasl_callback_hook_set(s->sasl->ctx, s); + gsasl_callback_set(s->sasl->ctx, rexmpp_sasl_cb); return 0; } void rexmpp_sasl_ctx_deinit (rexmpp_t *s) { - gsasl_done(s->sasl.ctx); + gsasl_done(s->sasl->ctx); + if (s->sasl != NULL) { + free(s->sasl); + s->sasl = NULL; + } } void rexmpp_sasl_ctx_cleanup (rexmpp_t *s) { - gsasl_finish(s->sasl.session); - s->sasl.session = NULL; + gsasl_finish(s->sasl->session); + s->sasl->session = NULL; } int rexmpp_sasl_encode (rexmpp_t *s, const char *in, size_t in_len, char **out, size_t *out_len) { - int sasl_err = gsasl_encode (s->sasl.session, in, in_len, out, out_len); + int sasl_err = gsasl_encode (s->sasl->session, in, in_len, out, out_len); if (sasl_err != GSASL_OK) { rexmpp_log(s, LOG_ERR, "SASL encoding error: %s", gsasl_strerror(sasl_err)); return -1; @@ -61,7 +66,7 @@ int rexmpp_sasl_encode (rexmpp_t *s, const char *in, size_t in_len, char **out, } int rexmpp_sasl_decode (rexmpp_t *s, const char *in, size_t in_len, char **out, size_t *out_len) { - int sasl_err = gsasl_decode(s->sasl.session, in, in_len, out, out_len); + int sasl_err = gsasl_decode(s->sasl->session, in, in_len, out, out_len); if (sasl_err != GSASL_OK) { rexmpp_log(s, LOG_ERR, "SASL decoding error: %s", gsasl_strerror(sasl_err)); return -1; @@ -70,15 +75,15 @@ int rexmpp_sasl_decode (rexmpp_t *s, const char *in, size_t in_len, char **out, } const char *rexmpp_sasl_suggest_mechanism (rexmpp_t *s, const char *mech_list) { - return gsasl_client_suggest_mechanism(s->sasl.ctx, mech_list); + return gsasl_client_suggest_mechanism(s->sasl->ctx, mech_list); } void rexmpp_sasl_property_set (rexmpp_t *s, rexmpp_sasl_property prop, const char *data) { - gsasl_property_set (s->sasl.session, (Gsasl_property)prop, data); + gsasl_property_set (s->sasl->session, (Gsasl_property)prop, data); } int rexmpp_sasl_start (rexmpp_t *s, const char *mech) { - int sasl_err = gsasl_client_start(s->sasl.ctx, mech, &(s->sasl.session)); + int sasl_err = gsasl_client_start(s->sasl->ctx, mech, &(s->sasl->session)); if (sasl_err != GSASL_OK) { rexmpp_log(s, LOG_CRIT, "Failed to initialise SASL session: %s", gsasl_strerror(sasl_err)); @@ -88,7 +93,7 @@ int rexmpp_sasl_start (rexmpp_t *s, const char *mech) { } int rexmpp_sasl_step64 (rexmpp_t *s, const char *b64_in, char **b64_out) { - int sasl_err = gsasl_step64 (s->sasl.session, b64_in, b64_out); + int sasl_err = gsasl_step64 (s->sasl->session, b64_in, b64_out); if (sasl_err != GSASL_OK) { if (sasl_err == GSASL_NEEDS_MORE) { rexmpp_log(s, LOG_DEBUG, "SASL needs more data"); @@ -106,26 +111,30 @@ int rexmpp_sasl_step64 (rexmpp_t *s, const char *b64_in, char **b64_out) { #include <memory.h> int rexmpp_sasl_ctx_init (rexmpp_t *s) { - s->sasl.mech = REXMPP_SASL_MECH_UNKNOWN; - s->sasl.authid = NULL; - s->sasl.password = NULL; + s->sasl = malloc(sizeof(struct rexmpp_sasl_ctx)); + s->sasl->mech = REXMPP_SASL_MECH_UNKNOWN; + s->sasl->authid = NULL; + s->sasl->password = NULL; return 0; } void rexmpp_sasl_ctx_cleanup (rexmpp_t *s) { - s->sasl.mech = REXMPP_SASL_MECH_UNKNOWN; - if (s->sasl.authid != NULL) { - free(s->sasl.authid); - s->sasl.authid = NULL; + s->sasl->mech = REXMPP_SASL_MECH_UNKNOWN; + if (s->sasl->authid != NULL) { + free(s->sasl->authid); + s->sasl->authid = NULL; } - if (s->sasl.password != NULL) { - free(s->sasl.password); - s->sasl.password = NULL; + if (s->sasl->password != NULL) { + free(s->sasl->password); + s->sasl->password = NULL; } } void rexmpp_sasl_ctx_deinit (rexmpp_t *s) { - (void)s; + if (s->sasl != NULL) { + free(s->sasl); + s->sasl = NULL; + } } int rexmpp_sasl_encode (rexmpp_t *s, const char *in, size_t in_len, char **out, size_t *out_len) { @@ -186,7 +195,7 @@ const char *rexmpp_sasl_suggest_mechanism (rexmpp_t *s, const char *mech_list) { int rexmpp_sasl_start (rexmpp_t *s, const char *mech) { rexmpp_sasl_mechanism m = rexmpp_sasl_mech_read(mech); if (m != REXMPP_SASL_MECH_UNKNOWN) { - s->sasl.mech = m; + s->sasl->mech = m; return 0; } return -1; @@ -194,15 +203,15 @@ int rexmpp_sasl_start (rexmpp_t *s, const char *mech) { const char *rexmpp_sasl_get_prop (rexmpp_t *s, rexmpp_sasl_property prop) { if (prop == REXMPP_SASL_PROP_AUTHID) { - if (s->sasl.authid == NULL) { + if (s->sasl->authid == NULL) { s->sasl_property_cb(s, prop); } - return s->sasl.authid; + return s->sasl->authid; } else if (prop == REXMPP_SASL_PROP_PASSWORD) { - if (s->sasl.password == NULL) { + if (s->sasl->password == NULL) { s->sasl_property_cb(s, prop); } - return s->sasl.password; + return s->sasl->password; } return NULL; } @@ -210,7 +219,7 @@ const char *rexmpp_sasl_get_prop (rexmpp_t *s, rexmpp_sasl_property prop) { int rexmpp_sasl_step64 (rexmpp_t *s, const char *b64_in, char **b64_out) { (void)s; (void)b64_in; - if (s->sasl.mech == REXMPP_SASL_MECH_PLAIN) { + if (s->sasl->mech == REXMPP_SASL_MECH_PLAIN) { /* RFC 4616 */ const char *authid = rexmpp_sasl_get_prop(s, REXMPP_SASL_PROP_AUTHID); const char *password = rexmpp_sasl_get_prop(s, REXMPP_SASL_PROP_PASSWORD); @@ -226,7 +235,7 @@ int rexmpp_sasl_step64 (rexmpp_t *s, const char *b64_in, char **b64_out) { free(auth); return 0; } - } else if (s->sasl.mech == REXMPP_SASL_MECH_EXTERNAL) { + } else if (s->sasl->mech == REXMPP_SASL_MECH_EXTERNAL) { *b64_out = strdup(""); return 0; } @@ -237,15 +246,15 @@ void rexmpp_sasl_property_set (rexmpp_t *s, rexmpp_sasl_property prop, const cha (void)s; (void)data; if (prop == REXMPP_SASL_PROP_AUTHID) { - if (s->sasl.authid != NULL) { - free(s->sasl.authid); + if (s->sasl->authid != NULL) { + free(s->sasl->authid); } - s->sasl.authid = strdup(data); + s->sasl->authid = strdup(data); } else if (prop == REXMPP_SASL_PROP_PASSWORD) { - if (s->sasl.password != NULL) { - free(s->sasl.password); + if (s->sasl->password != NULL) { + free(s->sasl->password); } - s->sasl.password = strdup(data); + s->sasl->password = strdup(data); } } diff --git a/src/rexmpp_tls.c b/src/rexmpp_tls.c index 7919556..96c042a 100644 --- a/src/rexmpp_tls.c +++ b/src/rexmpp_tls.c @@ -25,15 +25,15 @@ #if defined(USE_OPENSSL) rexmpp_tls_err_t rexmpp_process_openssl_ret (rexmpp_t *s, int ret) { - int err = SSL_get_error(s->tls.openssl_conn, ret); - s->tls.openssl_direction = REXMPP_OPENSSL_NONE; + int err = SSL_get_error(s->tls->openssl_conn, ret); + s->tls->openssl_direction = REXMPP_OPENSSL_NONE; if (ret == 1) { return REXMPP_TLS_SUCCESS; } else if (err == SSL_ERROR_WANT_READ) { - s->tls.openssl_direction = REXMPP_OPENSSL_READ; + s->tls->openssl_direction = REXMPP_OPENSSL_READ; return REXMPP_TLS_E_AGAIN; } else if (err == SSL_ERROR_WANT_WRITE) { - s->tls.openssl_direction = REXMPP_OPENSSL_WRITE; + s->tls->openssl_direction = REXMPP_OPENSSL_WRITE; return REXMPP_TLS_E_AGAIN; } else { rexmpp_log(s, LOG_ERR, "OpenSSL error %d", err); @@ -43,27 +43,28 @@ rexmpp_tls_err_t rexmpp_process_openssl_ret (rexmpp_t *s, int ret) { #endif int rexmpp_tls_init (rexmpp_t *s) { + s->tls = malloc(sizeof(struct rexmpp_tls)); #if defined(USE_GNUTLS) int err; - s->tls.tls_session_data = NULL; - s->tls.tls_session_data_size = 0; + s->tls->tls_session_data = NULL; + s->tls->tls_session_data_size = 0; - err = gnutls_certificate_allocate_credentials(&(s->tls.gnutls_cred)); + err = gnutls_certificate_allocate_credentials(&(s->tls->gnutls_cred)); if (err) { rexmpp_log(s, LOG_CRIT, "gnutls credentials allocation error: %s", gnutls_strerror(err)); return 1; } - err = gnutls_certificate_set_x509_system_trust(s->tls.gnutls_cred); + err = gnutls_certificate_set_x509_system_trust(s->tls->gnutls_cred); if (err < 0) { rexmpp_log(s, LOG_CRIT, "Certificates loading error: %s", gnutls_strerror(err)); return 1; } #ifdef ENABLE_CALLS - err = gnutls_certificate_allocate_credentials(&(s->jingle.dtls_cred)); + err = gnutls_certificate_allocate_credentials(&(s->tls->dtls_cred)); if (err) { - gnutls_certificate_free_credentials(s->tls.gnutls_cred); + gnutls_certificate_free_credentials(s->tls->gnutls_cred); rexmpp_log(s, LOG_CRIT, "gnutls credentials allocation error: %s", gnutls_strerror(err)); return 1; @@ -73,23 +74,23 @@ int rexmpp_tls_init (rexmpp_t *s) { #elif defined(USE_OPENSSL) SSL_library_init(); SSL_load_error_strings(); - s->tls.openssl_direction = REXMPP_OPENSSL_NONE; - s->tls.openssl_conn = NULL; - s->tls.openssl_ctx = SSL_CTX_new(TLS_client_method()); - if (s->tls.openssl_ctx == NULL) { + s->tls->openssl_direction = REXMPP_OPENSSL_NONE; + s->tls->openssl_conn = NULL; + s->tls->openssl_ctx = SSL_CTX_new(TLS_client_method()); + if (s->tls->openssl_ctx == NULL) { rexmpp_log(s, LOG_CRIT, "OpenSSL context creation error"); return 1; } - SSL_CTX_set_verify(s->tls.openssl_ctx, SSL_VERIFY_PEER, NULL); - if (SSL_CTX_set_default_verify_paths(s->tls.openssl_ctx) == 0) { + SSL_CTX_set_verify(s->tls->openssl_ctx, SSL_VERIFY_PEER, NULL); + if (SSL_CTX_set_default_verify_paths(s->tls->openssl_ctx) == 0) { rexmpp_log(s, LOG_CRIT, "Failed to set default verify paths for OpenSSL context"); - SSL_CTX_free(s->tls.openssl_ctx); - s->tls.openssl_ctx = NULL; + SSL_CTX_free(s->tls->openssl_ctx); + s->tls->openssl_ctx = NULL; return 1; } return 0; #else - (void)s; + s->tls = NULL; return 0; #endif } @@ -99,13 +100,13 @@ void rexmpp_tls_cleanup (rexmpp_t *s) { if (s->tls_state != REXMPP_TLS_INACTIVE && s->tls_state != REXMPP_TLS_AWAITING_DIRECT) { #if defined(USE_GNUTLS) - gnutls_deinit(s->tls.gnutls_session); + gnutls_deinit(s->tls->gnutls_session); #elif defined(USE_OPENSSL) - if (s->tls.openssl_conn != NULL) { - SSL_free(s->tls.openssl_conn); - s->tls.openssl_conn = NULL; + if (s->tls->openssl_conn != NULL) { + SSL_free(s->tls->openssl_conn); + s->tls->openssl_conn = NULL; } - s->tls.openssl_direction = REXMPP_OPENSSL_NONE; + s->tls->openssl_direction = REXMPP_OPENSSL_NONE; #else (void)s; #endif @@ -114,22 +115,24 @@ void rexmpp_tls_cleanup (rexmpp_t *s) { void rexmpp_tls_deinit (rexmpp_t *s) { #if defined(USE_GNUTLS) - gnutls_certificate_free_credentials(s->tls.gnutls_cred); - if (s->tls.tls_session_data != NULL) { - free(s->tls.tls_session_data); - s->tls.tls_session_data = NULL; + gnutls_certificate_free_credentials(s->tls->gnutls_cred); + if (s->tls->tls_session_data != NULL) { + free(s->tls->tls_session_data); + s->tls->tls_session_data = NULL; } #ifdef ENABLE_CALLS - gnutls_certificate_free_credentials(s->jingle.dtls_cred); + gnutls_certificate_free_credentials(s->tls->dtls_cred); #endif #elif defined(USE_OPENSSL) - if (s->tls.openssl_ctx != NULL) { - SSL_CTX_free(s->tls.openssl_ctx); + if (s->tls->openssl_ctx != NULL) { + SSL_CTX_free(s->tls->openssl_ctx); } - s->tls.openssl_ctx = NULL; -#else - (void)s; + s->tls->openssl_ctx = NULL; #endif + if (s->tls != NULL) { + free(s->tls); + s->tls = NULL; + } } rexmpp_tls_err_t @@ -138,33 +141,33 @@ rexmpp_tls_connect (rexmpp_t *s) { if (s->tls_state != REXMPP_TLS_HANDSHAKE) { gnutls_datum_t xmpp_client_protocol = {"xmpp-client", strlen("xmpp-client")}; rexmpp_log(s, LOG_DEBUG, "starting TLS"); - gnutls_init(&s->tls.gnutls_session, GNUTLS_CLIENT); - gnutls_session_set_ptr(s->tls.gnutls_session, s); - gnutls_alpn_set_protocols(s->tls.gnutls_session, &xmpp_client_protocol, 1, 0); - gnutls_server_name_set(s->tls.gnutls_session, GNUTLS_NAME_DNS, + gnutls_init(&s->tls->gnutls_session, GNUTLS_CLIENT); + gnutls_session_set_ptr(s->tls->gnutls_session, s); + gnutls_alpn_set_protocols(s->tls->gnutls_session, &xmpp_client_protocol, 1, 0); + gnutls_server_name_set(s->tls->gnutls_session, GNUTLS_NAME_DNS, s->initial_jid.domain, strlen(s->initial_jid.domain)); - gnutls_set_default_priority(s->tls.gnutls_session); - gnutls_credentials_set(s->tls.gnutls_session, GNUTLS_CRD_CERTIFICATE, - s->tls.gnutls_cred); - gnutls_transport_set_int(s->tls.gnutls_session, s->server_socket); - gnutls_handshake_set_timeout(s->tls.gnutls_session, + gnutls_set_default_priority(s->tls->gnutls_session); + gnutls_credentials_set(s->tls->gnutls_session, GNUTLS_CRD_CERTIFICATE, + s->tls->gnutls_cred); + gnutls_transport_set_int(s->tls->gnutls_session, s->server_socket); + gnutls_handshake_set_timeout(s->tls->gnutls_session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); - if (s->tls.tls_session_data != NULL) { - int ret = gnutls_session_set_data(s->tls.gnutls_session, - s->tls.tls_session_data, - s->tls.tls_session_data_size); + if (s->tls->tls_session_data != NULL) { + int ret = gnutls_session_set_data(s->tls->gnutls_session, + s->tls->tls_session_data, + s->tls->tls_session_data_size); if (ret != GNUTLS_E_SUCCESS) { rexmpp_log(s, LOG_WARNING, "Failed to set TLS session data: %s", gnutls_strerror(ret)); - free(s->tls.tls_session_data); - s->tls.tls_session_data = NULL; - s->tls.tls_session_data_size = 0; + free(s->tls->tls_session_data); + s->tls->tls_session_data = NULL; + s->tls->tls_session_data_size = 0; } } } - int ret = gnutls_handshake(s->tls.gnutls_session); + int ret = gnutls_handshake(s->tls->gnutls_session); if (ret == GNUTLS_E_AGAIN) { rexmpp_log(s, LOG_DEBUG, "Waiting for TLS handshake to complete"); return REXMPP_TLS_E_AGAIN; @@ -190,7 +193,7 @@ rexmpp_tls_connect (rexmpp_t *s) { service/source host (<https://tools.ietf.org/html/rfc7712#section-5.1>, <https://tools.ietf.org/html/rfc7673#section-6>). */ - ret = dane_verify_session_crt(NULL, s->tls.gnutls_session, s->server_host, + ret = dane_verify_session_crt(NULL, s->tls->gnutls_session, s->server_host, "tcp", s->server_port, 0, 0, &status); if (ret) { rexmpp_log(s, LOG_WARNING, "DANE verification error: %s", @@ -212,7 +215,7 @@ rexmpp_tls_connect (rexmpp_t *s) { } } - ret = gnutls_certificate_verify_peers3(s->tls.gnutls_session, + ret = gnutls_certificate_verify_peers3(s->tls->gnutls_session, s->initial_jid.domain, &status); if (ret || status) { @@ -224,23 +227,23 @@ rexmpp_tls_connect (rexmpp_t *s) { } else { rexmpp_log(s, LOG_ERR, "Untrusted certificate"); } - gnutls_bye(s->tls.gnutls_session, GNUTLS_SHUT_RDWR); + gnutls_bye(s->tls->gnutls_session, GNUTLS_SHUT_RDWR); return REXMPP_TLS_E_OTHER; } - if (gnutls_session_is_resumed(s->tls.gnutls_session)) { + if (gnutls_session_is_resumed(s->tls->gnutls_session)) { rexmpp_log(s, LOG_INFO, "TLS session is resumed"); } else { - if (s->tls.tls_session_data != NULL) { + if (s->tls->tls_session_data != NULL) { rexmpp_log(s, LOG_DEBUG, "TLS session is not resumed"); - free(s->tls.tls_session_data); - s->tls.tls_session_data = NULL; + free(s->tls->tls_session_data); + s->tls->tls_session_data = NULL; } - gnutls_session_get_data(s->tls.gnutls_session, NULL, - &s->tls.tls_session_data_size); - s->tls.tls_session_data = malloc(s->tls.tls_session_data_size); - ret = gnutls_session_get_data(s->tls.gnutls_session, s->tls.tls_session_data, - &s->tls.tls_session_data_size); + gnutls_session_get_data(s->tls->gnutls_session, NULL, + &s->tls->tls_session_data_size); + s->tls->tls_session_data = malloc(s->tls->tls_session_data_size); + ret = gnutls_session_get_data(s->tls->gnutls_session, s->tls->tls_session_data, + &s->tls->tls_session_data_size); if (ret != GNUTLS_E_SUCCESS) { rexmpp_log(s, LOG_ERR, "Failed to get TLS session data: %s", gnutls_strerror(ret)); @@ -256,26 +259,26 @@ rexmpp_tls_connect (rexmpp_t *s) { } #elif defined(USE_OPENSSL) if (s->tls_state != REXMPP_TLS_HANDSHAKE) { - s->tls.openssl_conn = SSL_new(s->tls.openssl_ctx); - if (s->tls.openssl_conn == NULL) { + s->tls->openssl_conn = SSL_new(s->tls->openssl_ctx); + if (s->tls->openssl_conn == NULL) { rexmpp_log(s, LOG_ERR, "Failed to create an OpenSSL connection object"); return REXMPP_TLS_E_OTHER; } - if (SSL_set_fd(s->tls.openssl_conn, s->server_socket) == 0) { + if (SSL_set_fd(s->tls->openssl_conn, s->server_socket) == 0) { rexmpp_log(s, LOG_ERR, "Failed to set a file descriptor for OpenSSL connection"); return REXMPP_TLS_E_OTHER; } - if (SSL_set1_host(s->tls.openssl_conn, s->initial_jid.domain) == 0) { + if (SSL_set1_host(s->tls->openssl_conn, s->initial_jid.domain) == 0) { rexmpp_log(s, LOG_ERR, "Failed to set a hostname for OpenSSL connection"); return REXMPP_TLS_E_OTHER; } /* For SNI */ - if (SSL_set_tlsext_host_name(s->tls.openssl_conn, s->initial_jid.domain) == 0) { + if (SSL_set_tlsext_host_name(s->tls->openssl_conn, s->initial_jid.domain) == 0) { rexmpp_log(s, LOG_ERR, "Failed to set a tlsext hostname for OpenSSL connection"); return REXMPP_TLS_E_OTHER; } } - return rexmpp_process_openssl_ret(s, SSL_connect(s->tls.openssl_conn)); + return rexmpp_process_openssl_ret(s, SSL_connect(s->tls->openssl_conn)); #else rexmpp_log(s, LOG_ERR, "rexmpp is compiled without TLS support"); return REXMPP_TLS_E_OTHER; @@ -285,7 +288,7 @@ rexmpp_tls_connect (rexmpp_t *s) { rexmpp_tls_err_t rexmpp_tls_disconnect (rexmpp_t *s) { #if defined(USE_GNUTLS) - int ret = gnutls_bye(s->tls.gnutls_session, GNUTLS_SHUT_RDWR); + int ret = gnutls_bye(s->tls->gnutls_session, GNUTLS_SHUT_RDWR); if (ret == GNUTLS_E_SUCCESS) { return REXMPP_TLS_SUCCESS; } else { @@ -294,9 +297,9 @@ rexmpp_tls_disconnect (rexmpp_t *s) { return REXMPP_TLS_E_OTHER; } #elif defined(USE_OPENSSL) - int ret = SSL_shutdown(s->tls.openssl_conn); + int ret = SSL_shutdown(s->tls->openssl_conn); if (ret == 0) { - s->tls.openssl_direction = REXMPP_OPENSSL_READ; + s->tls->openssl_direction = REXMPP_OPENSSL_READ; return REXMPP_TLS_E_AGAIN; } else { return rexmpp_process_openssl_ret(s, ret); @@ -312,7 +315,7 @@ rexmpp_tls_send (rexmpp_t *s, void *data, size_t data_size, ssize_t *written) { #if defined(USE_GNUTLS) *written = -1; - ssize_t ret = gnutls_record_send(s->tls.gnutls_session, + ssize_t ret = gnutls_record_send(s->tls->gnutls_session, data, data_size); if (ret >= 0) { @@ -326,7 +329,7 @@ rexmpp_tls_send (rexmpp_t *s, void *data, size_t data_size, ssize_t *written) } #elif defined(USE_OPENSSL) *written = -1; - int ret = SSL_write_ex(s->tls.openssl_conn, data, data_size, written); + int ret = SSL_write_ex(s->tls->openssl_conn, data, data_size, written); if (ret > 0) { return REXMPP_TLS_SUCCESS; } else { @@ -345,7 +348,7 @@ rexmpp_tls_err_t rexmpp_tls_recv (rexmpp_t *s, void *data, size_t data_size, ssize_t *received) { #if defined(USE_GNUTLS) *received = -1; - ssize_t ret = gnutls_record_recv(s->tls.gnutls_session, data, data_size); + ssize_t ret = gnutls_record_recv(s->tls->gnutls_session, data, data_size); if (ret >= 0) { *received = ret; return REXMPP_TLS_SUCCESS; @@ -357,7 +360,7 @@ rexmpp_tls_recv (rexmpp_t *s, void *data, size_t data_size, ssize_t *received) { } #elif defined(USE_OPENSSL) *received = -1; - int ret = SSL_read_ex(s->tls.openssl_conn, data, data_size, received); + int ret = SSL_read_ex(s->tls->openssl_conn, data, data_size, received); if (ret > 0) { return REXMPP_TLS_SUCCESS; } else { @@ -374,18 +377,18 @@ rexmpp_tls_recv (rexmpp_t *s, void *data, size_t data_size, ssize_t *received) { int rexmpp_tls_fds (rexmpp_t *s, fd_set *read_fds, fd_set *write_fds) { #if defined(USE_GNUTLS) - if (gnutls_record_get_direction(s->tls.gnutls_session) == 0) { + if (gnutls_record_get_direction(s->tls->gnutls_session) == 0) { FD_SET(s->server_socket, read_fds); } else { FD_SET(s->server_socket, write_fds); } return s->server_socket + 1; #elif defined(USE_OPENSSL) - if (s->tls.openssl_direction == REXMPP_OPENSSL_READ) { + if (s->tls->openssl_direction == REXMPP_OPENSSL_READ) { FD_SET(s->server_socket, read_fds); return s->server_socket + 1; } - if (s->tls.openssl_direction == REXMPP_OPENSSL_WRITE) { + if (s->tls->openssl_direction == REXMPP_OPENSSL_WRITE) { FD_SET(s->server_socket, write_fds); return s->server_socket + 1; } @@ -404,12 +407,12 @@ rexmpp_tls_set_x509_key_file (rexmpp_t *s, const char *key_file) { #if defined(USE_GNUTLS) - int ret = gnutls_certificate_set_x509_key_file(s->tls.gnutls_cred, + int ret = gnutls_certificate_set_x509_key_file(s->tls->gnutls_cred, cert_file, key_file, GNUTLS_X509_FMT_PEM); #ifdef ENABLE_CALLS - gnutls_certificate_set_x509_key_file(s->jingle.dtls_cred, + gnutls_certificate_set_x509_key_file(s->tls->dtls_cred, cert_file, key_file, GNUTLS_X509_FMT_PEM); @@ -422,13 +425,13 @@ rexmpp_tls_set_x509_key_file (rexmpp_t *s, return REXMPP_TLS_E_OTHER; } #elif defined(USE_OPENSSL) - if (SSL_CTX_use_certificate_file(s->tls.openssl_ctx, + if (SSL_CTX_use_certificate_file(s->tls->openssl_ctx, cert_file, SSL_FILETYPE_PEM) != 1) { rexmpp_log(s, LOG_ERR, "Failed to set a certificate file"); return REXMPP_TLS_E_OTHER; } - if (SSL_CTX_use_PrivateKey_file(s->tls.openssl_ctx, + if (SSL_CTX_use_PrivateKey_file(s->tls->openssl_ctx, key_file, SSL_FILETYPE_PEM) != 1) { rexmpp_log(s, LOG_ERR, "Failed to set a key file"); @@ -448,12 +451,12 @@ rexmpp_tls_set_x509_trust_file (rexmpp_t *s, const char *cert_file) { #if defined(USE_GNUTLS) - gnutls_certificate_set_x509_trust_file(s->tls.gnutls_cred, + gnutls_certificate_set_x509_trust_file(s->tls->gnutls_cred, cert_file, GNUTLS_X509_FMT_PEM); return REXMPP_TLS_SUCCESS; #elif defined(USE_OPENSSL) - if (SSL_CTX_load_verify_locations(s->tls.openssl_ctx, cert_file, NULL) != 1) { + if (SSL_CTX_load_verify_locations(s->tls->openssl_ctx, cert_file, NULL) != 1) { rexmpp_log(s, LOG_ERR, "Failed to set a trusted certificate file"); return REXMPP_TLS_E_OTHER; } diff --git a/src/rexmpp_tls.h b/src/rexmpp_tls.h index 24ba042..4406ca7 100644 --- a/src/rexmpp_tls.h +++ b/src/rexmpp_tls.h @@ -43,6 +43,7 @@ struct rexmpp_tls { size_t tls_session_data_size; gnutls_session_t gnutls_session; gnutls_certificate_credentials_t gnutls_cred; + gnutls_certificate_credentials_t dtls_cred; }; #elif defined(USE_OPENSSL) #include <openssl/ssl.h> |