int iks_send_raw (iksparser *prs, const char *xmlstr) { struct stream_data *data = iks_user_data (prs); int ret; #ifdef HAVE_GNUTLS if (data->flags & SF_SECURE) { if (gnutls_record_send (data->sess, xmlstr, strlen (xmlstr)) < 0) return IKS_NET_RWERR; } else #elif HAVE_SSL if (data->flags & SF_SECURE) { if (SSL_write(data->ssl, xmlstr, strlen (xmlstr)) < 0) return IKS_NET_RWERR; } else #endif { ret = data->trans->send (data->sock, xmlstr, strlen (xmlstr)); if (ret) return ret; } if (data->logHook) data->logHook (data->user_data, xmlstr, strlen (xmlstr), 0); return IKS_OK; }
int iks_connect_async_with (iksparser *prs, const char *server, int port, const char *server_name, ikstransport *trans, void *notify_data, iksAsyncNotify *notify_func) { struct stream_data *data = iks_user_data (prs); int ret; if (NULL == trans->connect_async) return IKS_NET_NOTSUPP; if (!data->buf) { data->buf = iks_stack_alloc (data->s, NET_IO_BUF_SIZE); if (NULL == data->buf) return IKS_NOMEM; } ret = trans->connect_async (prs, &data->sock, server, server_name, port, notify_data, notify_func); if (ret) return ret; data->trans = trans; data->server = server_name; return IKS_OK; }
int iks_start_sasl (iksparser *prs, enum ikssasltype type, char *username, char *pass) { iks *x; x = iks_new ("auth"); iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL); switch (type) { case IKS_SASL_PLAIN: { int len = iks_strlen (username) + iks_strlen (pass) + 2; char *s = iks_malloc (80+len); char *base64; iks_insert_attrib (x, "mechanism", "PLAIN"); sprintf (s, "%c%s%c%s", 0, username, 0, pass); base64 = iks_base64_encode (s, len); iks_insert_cdata (x, base64, 0); iks_free (base64); iks_free (s); break; } case IKS_SASL_DIGEST_MD5: { struct stream_data *data = iks_user_data (prs); iks_insert_attrib (x, "mechanism", "DIGEST-MD5"); data->auth_username = username; data->auth_pass = pass; break; } default: iks_delete (x); return IKS_NET_NOTSUPP; } iks_send (prs, x); iks_delete (x); return IKS_OK; }
int iks_is_secure(iksparser *prs) { struct stream_data *data = iks_user_data(prs); return data->flags & SF_SECURE; }
int iks_fd(iksparser *prs) { struct stream_data *data = iks_user_data(prs); return (int) data->sock; }
void iks_set_log_hook(iksparser *prs, iksLogHook *logHook) { struct stream_data *data = iks_user_data(prs); data->logHook = logHook; }
void *iks_stream_user_data(iksparser *prs) { struct stream_data *data = iks_user_data(prs); return data->user_data; }
int iks_recv (iksparser *prs, int timeout) { struct stream_data *data = iks_user_data (prs); int len, ret; #ifdef HAVE_SSL int err; #endif while (1) { #ifdef HAVE_GNUTLS if (data->flags & SF_SECURE) { len = gnutls_record_recv (data->sess, data->buf, NET_IO_BUF_SIZE - 1); if (len == 0) len = -1; } else #elif HAVE_SSL if (data->flags & SF_SECURE) { ret = sock_read_ready(data, timeout*1000); if (ret == -1) { return IKS_NET_TLSFAIL; } else if( ret == 0 ) { return IKS_OK; } else { len = SSL_read(data->ssl, data->buf, NET_IO_BUF_SIZE - 1); } if( len <= 0 ) { switch( err = SSL_get_error(data->ssl, len) ) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: return IKS_OK; break; default: if(data->logHook) data->logHook(data->user_data, ERR_error_string(err, NULL), strlen(ERR_error_string(err, NULL)), 1); return IKS_NET_TLSFAIL; break; } } } else #endif { len = data->trans->recv (data->sock, data->buf, NET_IO_BUF_SIZE - 1, timeout); } if (len < 0) return IKS_NET_RWERR; if (len == 0) break; data->buf[len] = '\0'; if (data->logHook) data->logHook (data->user_data, data->buf, len, 1); ret = iks_parse (prs, data->buf, len, 0); if (ret != IKS_OK) return ret; if (!data->trans) { /* stream hook called iks_disconnect */ return IKS_NET_NOCONN; } timeout = 0; } return IKS_OK; }