static int handshake (struct stream_data *data) { const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 }; const int kx_priority[] = { GNUTLS_KX_RSA, 0 }; const int cipher_priority[] = { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0}; const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 }; const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 }; int ret; #ifndef WIN32 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); #endif if (gnutls_global_init () != 0) return IKS_NOMEM; if (gnutls_certificate_allocate_credentials (&data->cred) < 0) return IKS_NOMEM; if (gnutls_init (&data->sess, GNUTLS_CLIENT) != 0) { gnutls_certificate_free_credentials (data->cred); return IKS_NOMEM; } gnutls_protocol_set_priority (data->sess, protocol_priority); gnutls_cipher_set_priority(data->sess, cipher_priority); gnutls_compression_set_priority(data->sess, comp_priority); gnutls_kx_set_priority(data->sess, kx_priority); gnutls_mac_set_priority(data->sess, mac_priority); gnutls_credentials_set (data->sess, GNUTLS_CRD_CERTIFICATE, data->cred); gnutls_transport_set_push_function (data->sess, (gnutls_push_func) tls_push); gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func) tls_pull); gnutls_transport_set_ptr (data->sess, data->prs); ret = gnutls_handshake (data->sess); if (ret != 0) { gnutls_deinit (data->sess); gnutls_certificate_free_credentials (data->cred); return IKS_NET_TLSFAIL; } data->flags &= (~SF_TRY_SECURE); data->flags |= SF_SECURE; iks_send_header (data->prs, data->server); return IKS_OK; } // HAVE_GNUTLS
int iks_recv(iksparser *prs, int timeout) { struct stream_data *data = iks_user_data(prs); int len, ret; while(1) { if(data->flags & SF_SECURE_AGAIN) { len = iks_default_tls.send(data->tlsdata, NULL, 0); if(len >= 0) { data->flags &= (~SF_SECURE_AGAIN); data->flags |= SF_SECURE; if((len = iks_send_header(data->prs, data->server) != IKS_OK)) { data->flags &= (~SF_SECURE); data->flags |= SF_SECURE_AGAIN; } len = 0; } } else if(data->flags & SF_SECURE) { len = iks_default_tls.recv(data->tlsdata, data->buf, NET_IO_BUF_SIZE - 1, timeout); } else { 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; }
static int handshake (struct stream_data *data) { int ret; int finished; SSL_library_init(); SSL_load_error_strings(); data->ssl_ctx = SSL_CTX_new(TLSv1_method()); if(!data->ssl_ctx) return IKS_NOMEM; data->ssl = SSL_new(data->ssl_ctx); if(!data->ssl) return IKS_NOMEM; if( SSL_set_fd(data->ssl, (int)(intptr_t)data->sock) != 1 ) return IKS_NOMEM; /* Set both the read and write BIO's to non-blocking mode */ BIO_set_nbio(SSL_get_rbio(data->ssl), 1); BIO_set_nbio(SSL_get_wbio(data->ssl), 1); finished = 0; do { ret = SSL_connect(data->ssl); if( ret != 1 ) { if( wait_for_data(data, ret, 1) != IKS_OK ) { finished = 1; SSL_free(data->ssl); } } } while( ret != 1 && finished != 1 ); if( ret == 1 ) { data->flags &= (~SF_TRY_SECURE); data->flags |= SF_SECURE; iks_send_header (data->prs, data->server); } return ret == 1 ? IKS_OK : IKS_NET_TLSFAIL; }
int iks_connect_with(iksparser *prs, const char *server, int port, const char *server_name, ikstransport *trans) { struct stream_data *data = iks_user_data(prs); int ret; if(!trans->connect) 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(prs, &data->sock, server, port); if(ret) return ret; data->trans = trans; return iks_send_header(prs, server_name); }
static int tagHook(struct stream_data *data, char *name, char **atts, int type) { iks *x; int err; switch(type) { case IKS_OPEN: case IKS_SINGLE: if(data->flags & SF_TRY_SECURE) { if(strcmp(name, "proceed") == 0) { err = iks_default_tls.handshake(&data->tlsdata, data->trans, data->sock); if(err == IKS_OK) { data->flags &= (~SF_TRY_SECURE); data->flags |= SF_SECURE; iks_send_header(data->prs, data->server); } if(err == IKS_AGAIN) { data->flags &= (~SF_TRY_SECURE); data->flags |= SF_SECURE_AGAIN; err = IKS_OK; } return err; } else if(strcmp(name, "failure") == 0) { return IKS_NET_TLSFAIL; } } if(data->current) { x = iks_insert(data->current, name); insert_attribs(x, atts); } else { x = iks_new(name); insert_attribs(x, atts); if(iks_strcmp(name, "stream:stream") == 0) { err = data->streamHook(data->user_data, IKS_NODE_START, x); if(err != IKS_OK) return err; break; } } data->current = x; if(IKS_OPEN == type) break; case IKS_CLOSE: x = data->current; if(NULL == x) { err = data->streamHook(data->user_data, IKS_NODE_STOP, NULL); if(err != IKS_OK) return err; break; } if(NULL == iks_parent(x)) { data->current = NULL; if(iks_strcmp(name, "challenge") == 0) { iks_sasl_challenge(data, x); iks_delete(x); } else if(iks_strcmp(name, "stream:error") == 0) { err = data->streamHook(data->user_data, IKS_NODE_ERROR, x); if(err != IKS_OK) return err; } else { err = data->streamHook(data->user_data, IKS_NODE_NORMAL, x); if(err != IKS_OK) return err; } break; } data->current = iks_parent(x); } return IKS_OK; }
int axis2_xmpp_client_on_normal_node( axis2_xmpp_session_data_t *session, iks* node) { if(!strcmp("stream:features", iks_name(node))) { session->features = iks_stream_features(node); if(session->use_sasl) { if(session->use_tls && !iks_is_secure(session->parser)) { if(!session->authorized) { /* we might be in the process of establishing TLS. so should return OK */ return IKS_OK; } return IKS_HOOK; } if(session->authorized) { /* Bind a resource if required */ xmpp_process_msg(session, node); } else { if(session->features & IKS_STREAM_SASL_MD5) { iks_start_sasl(session->parser, IKS_SASL_DIGEST_MD5, session->jid->user, session->password); } else if(session->features & IKS_STREAM_SASL_PLAIN) { iks_start_sasl(session->parser, IKS_SASL_PLAIN, session->jid->user, session->password); } #ifdef AXIS2_XMPP_GSSAPI else if (session->features & IKS_STREAM_SASL_GSSAPI) { iks_start_sasl (session->parser, IKS_SASL_GSSAPI, session->jid->user, session->password); } #endif /* AXIS2_XMPP_GSSAPI */ } } else { /* features node */ if(!strcmp("stream:features", iks_name(node))) { if(session->authorized) xmpp_process_msg(session, node); } } } else if(!strcmp("failure", iks_name(node))) { AXIS2_LOG_ERROR(session->env->log, AXIS2_LOG_SI, "[xmpp]Authentication failed."); return IKS_HOOK; } else if(!strcmp("success", iks_name(node))) { AXIS2_LOG_INFO(session->env->log, "[xmpp]Authentication successful."); session->authorized = 1; iks_send_header(session->parser, session->server); } else { ikspak *pak; pak = iks_packet(node); iks_filter_packet(session->filter, pak); } return IKS_OK; }
static int on_stream (void *ptr, int type, iks *node) { iks *x; ikspak *pak; switch (type) { case IKS_NODE_START: /* x = iks_make_auth (j_user, prefs.pass, iks_find_attrib (node, "id")); iks_insert_attrib (x, "id", "auth"); iks_send (j_parser, x); iks_delete (x); */ break; case IKS_NODE_NORMAL: if (strcmp("stream:features", iks_name(node)) == 0) { if (authorized) { int features; features = iks_stream_features(node); if (features & IKS_STREAM_BIND) { x = iks_make_resource_bind(j_user); iks_send(j_parser, x); iks_delete(x); } if (features & IKS_STREAM_SESSION) { x = iks_make_session(); iks_insert_attrib(x, "id", "auth"); iks_send(j_parser, x); iks_delete(x); } } else { iks_start_sasl(j_parser, IKS_SASL_DIGEST_MD5, j_user->user, prefs.pass); } break; } else if (strcmp("failure", iks_name(node)) == 0) { log_event ("Hata: SASL başarısız!"); return IKS_HOOK; } else if (strcmp("success", iks_name(node)) == 0) { authorized = 1; iks_send_header(j_parser, j_user->server); break; } pak = iks_packet (node); if (pak->type == IKS_PAK_MESSAGE) { // process incoming messages command_parse (pak->from->partial, iks_find_cdata (node, "body")); } else if (pak->type == IKS_PAK_S10N) { // always accept subscriptions if (pak->subtype == IKS_TYPE_SUBSCRIBE) { x = iks_make_s10n (IKS_TYPE_SUBSCRIBED, pak->from->full, NULL); iks_send (j_parser, x); iks_delete (x); } } else if (pak->type == IKS_PAK_IQ) { if (iks_strcmp (pak->id, "auth") == 0) { // auth response if (pak->subtype == IKS_TYPE_RESULT) { log_event ("Bağlandık."); x = iks_make_iq (IKS_TYPE_GET, IKS_NS_ROSTER); iks_send (j_parser, x); iks_delete (x); x = iks_make_pres (IKS_SHOW_AVAILABLE, NULL); iks_send (j_parser, x); iks_delete (x); } else { log_event ("Hata: kullanıcı doğrulama başarısız oldu!"); return IKS_HOOK; } } } break; case IKS_NODE_STOP: case IKS_NODE_ERROR: log_event ("Hata: XMPP stream hatası!"); return IKS_HOOK; } if (node) iks_delete (node); return IKS_OK; }