⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stream.c

📁 linux平台或者windwos平台通用xml 解析器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* iksemel (XML parser for Jabber)** Copyright (C) 2000-2007 Gurer Ozen <madcat@e-kolay.net>** This code is free software; you can redistribute it and/or** modify it under the terms of GNU Lesser General Public License.*/#include "common.h"#include "iksemel.h"#ifdef HAVE_GNUTLS#include <gnutls/gnutls.h>#endif#define SF_FOREIGN 1#define SF_TRY_SECURE 2#define SF_SECURE 4struct stream_data {	iksparser *prs;	ikstack *s;	ikstransport *trans;	char *name_space;	void *user_data;	const char *server;	iksStreamHook *streamHook;	iksLogHook *logHook;	iks *current;	char *buf;	void *sock;	unsigned int flags;	char *auth_username;	char *auth_pass;#ifdef HAVE_GNUTLS	gnutls_session sess;	gnutls_certificate_credentials cred;#endif};#ifdef HAVE_GNUTLSstatic size_ttls_push (iksparser *prs, const char *buffer, size_t len){	struct stream_data *data = iks_user_data (prs);	int ret;	ret = data->trans->send (data->sock, buffer, len);	if (ret) return (size_t) -1;	return len;}static size_ttls_pull (iksparser *prs, char *buffer, size_t len){	struct stream_data *data = iks_user_data (prs);	int ret;	ret = data->trans->recv (data->sock, buffer, len, -1);	if (ret == -1) return (size_t) -1;	return ret;}static inthandshake (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;	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;}#endifstatic voidinsert_attribs (iks *x, char **atts){	if (atts) {		int i = 0;		while (atts[i]) {			iks_insert_attrib (x, atts[i], atts[i+1]);			i += 2;		}	}}#define CNONCE_LEN 4static voidparse_digest (char *message, const char *key, char **value_ptr, char **value_end_ptr){	char *t;	*value_ptr = NULL;	*value_end_ptr = NULL;	t = strstr(message, key);	if (t) {		t += strlen(key);		*value_ptr = t;		while (t[0] != '\0') {			if (t[0] != '\\' && t[1] == '"') {				++t;				*value_end_ptr = t;				return;			}			++t;		}	}}static iks *make_sasl_response (struct stream_data *data, char *message){	iks *x = NULL;	char *realm, *realm_end;	char *nonce, *nonce_end;	char cnonce[CNONCE_LEN*8 + 1];	iksmd5 *md5;	unsigned char a1_h[16], a1[33], a2[33], response_value[33];	char *response, *response_coded;	int i;	parse_digest(message, "realm=\"", &realm, &realm_end);	parse_digest(message, "nonce=\"", &nonce, &nonce_end);	/* nonce is necessary for auth */	if (!nonce || !nonce_end) return NULL;	*nonce_end = '\0';	/* if no realm is given use the server hostname */	if (realm) {		if (!realm_end) return NULL;		*realm_end = '\0';	} else {		realm = (char *) data->server;	}	/* generate random client challenge */	for (i = 0; i < CNONCE_LEN; ++i)		sprintf (cnonce + i*8, "%08x", rand());	md5 = iks_md5_new();	if (!md5) return NULL;	iks_md5_hash (md5, (const unsigned char*)data->auth_username, iks_strlen (data->auth_username), 0);	iks_md5_hash (md5, (const unsigned char*)":", 1, 0);	iks_md5_hash (md5, (const unsigned char*)realm, iks_strlen (realm), 0);	iks_md5_hash (md5, (const unsigned char*)":", 1, 0);	iks_md5_hash (md5, (const unsigned char*)data->auth_pass, iks_strlen (data->auth_pass), 1);	iks_md5_digest (md5, a1_h);	iks_md5_reset (md5);	iks_md5_hash (md5, (const unsigned char*)a1_h, 16, 0);	iks_md5_hash (md5, (const unsigned char*)":", 1, 0);	iks_md5_hash (md5, (const unsigned char*)nonce, iks_strlen (nonce), 0);	iks_md5_hash (md5, (const unsigned char*)":", 1, 0);	iks_md5_hash (md5, (const unsigned char*)cnonce, iks_strlen (cnonce), 1);	iks_md5_print (md5, (char*)a1);	iks_md5_reset (md5);	iks_md5_hash (md5, (const unsigned char*)"AUTHENTICATE:xmpp/", 18, 0);	iks_md5_hash (md5, (const unsigned char*)data->server, iks_strlen (data->server), 1);	iks_md5_print (md5, (char*)a2);	iks_md5_reset (md5);	iks_md5_hash (md5, (const unsigned char*)a1, 32, 0);	iks_md5_hash (md5, (const unsigned char*)":", 1, 0);	iks_md5_hash (md5, (const unsigned char*)nonce, iks_strlen (nonce), 0);	iks_md5_hash (md5, (const unsigned char*)":00000001:", 10, 0);	iks_md5_hash (md5, (const unsigned char*)cnonce, iks_strlen (cnonce), 0);	iks_md5_hash (md5, (const unsigned char*)":auth:", 6, 0);	iks_md5_hash (md5, (const unsigned char*)a2, 32, 1);	iks_md5_print (md5, (char*)response_value);	iks_md5_delete (md5);	i = iks_strlen (data->auth_username) + iks_strlen (realm) +		iks_strlen (nonce) + iks_strlen (data->server) +		CNONCE_LEN*8 + 136;	response = iks_malloc (i);	if (!response) return NULL;	sprintf (response, "username=\"%s\",realm=\"%s\",nonce=\"%s\""		",cnonce=\"%s\",nc=00000001,qop=auth,digest-uri=\""		"xmpp/%s\",response=%s,charset=utf-8",		data->auth_username, realm, nonce, cnonce,		data->server, response_value);	response_coded = iks_base64_encode (response, 0);	if (response_coded) {		x = iks_new ("response");		iks_insert_cdata (x, response_coded, 0);		iks_free (response_coded);	}	iks_free (response);	return x;}static voidiks_sasl_challenge (struct stream_data *data, iks *challenge){	char *message;	iks *x;	char *tmp;	tmp = iks_cdata (iks_child (challenge));	if (!tmp) return;	/* decode received blob */	message = iks_base64_decode (tmp);	if (!message) return;	/* reply the challenge */	if (strstr (message, "rspauth")) {		x = iks_new ("response");	} else {		x = make_sasl_response (data, message);	}	if (x) {		iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL);		iks_send (data->prs, x);		iks_delete (x);	}	iks_free (message);}static inttagHook (struct stream_data *data, char *name, char **atts, int type){	iks *x;	int err;	switch (type) {		case IKS_OPEN:		case IKS_SINGLE:#ifdef HAVE_GNUTLS			if (data->flags & SF_TRY_SECURE) {				if (strcmp (name, "proceed") == 0) {					err = handshake (data);					return err;				} else if (strcmp (name, "failure") == 0){					return IKS_NET_TLSFAIL;				}			}#endif			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);				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;}static int

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -