merge in new iksemel patches

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11645 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Brian West
2009-02-04 23:59:19 +00:00
parent 40b19bf28b
commit 2005e1862f
22 changed files with 7991 additions and 462 deletions
+1 -1
View File
@@ -24,6 +24,6 @@ libiksemel_la_SOURCES = \
md5.c \
base64.c
libiksemel_la_LDFLAGS = -version-info 3:0:0 -no-undefined
libiksemel_la_LDFLAGS = -version-info 4:0:1 -no-undefined
libiksemel_la_CFLAGS = $(CFLAGS) $(LIBGNUTLS_CFLAGS)
libiksemel_la_LIBADD = $(LIBGNUTLS_LIBS)
+14 -9
View File
@@ -7,27 +7,30 @@
#include "common.h"
#include "iksemel.h"
static char base64_charset[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char base64_charset[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *iks_base64_decode(const char *buf)
{
char *res, *save, *foo, val;
char *res, *save;
char val;
const char *foo;
const char *end;
int index;
size_t len;
if (!buf)
return NULL;
index = iks_strlen(buf)*6 / 8 + 1;
save = res = iks_malloc(index);
memset(res, 0, index);
index = 0;
len = iks_strlen(buf) * 6 / 8 + 1;
save = res = iks_malloc(len);
if (!save)
return NULL;
memset(res, 0, len);
index = 0;
end = buf + iks_strlen(buf);
while (*buf && buf < end) {
@@ -66,6 +69,7 @@ char *iks_base64_encode(const char *buf, int len)
len = (len > 0) ? (len) : (iks_strlen(buf));
save = res = iks_malloc((len*8) / 6 + 4);
if (!save) return NULL;
for (k = 0; k < len/3; ++k) {
*res++ = base64_charset[*buf >> 2];
@@ -85,14 +89,15 @@ char *iks_base64_encode(const char *buf, int len)
buf++;
*res++ = base64_charset[t | (*buf >> 4)];
*res++ = base64_charset[((*buf++ & 0x0F) << 2)];
*res++ = '=';
break;
case 1:
*res++ = base64_charset[*buf >> 2];
*res++ = base64_charset[(*buf++ & 0x03) << 4];
*res++ = '=';
*res++ = '=';
break;
}
*res++ = '=';
*res++ = '=';
*res = 0;
return save;
}
+4 -1
View File
@@ -37,6 +37,8 @@ tagHook (struct dom_data *data, char *name, char **atts, int type)
}
if (IKS_CLOSE == type || IKS_SINGLE == type) {
x = iks_parent (data->current);
if (iks_strcmp(iks_name(data->current), name) != 0)
return IKS_BADXML;
if (x)
data->current = x;
else {
@@ -130,8 +132,9 @@ iks_load (const char *fname, iks **xptr)
if (len < FILE_IO_BUF_SIZE) {
if (0 == feof (f)) {
ret = IKS_FILE_RWERR;
len = 0;
break;
}
if (0 == len) ret = IKS_OK;
done = 1;
}
if (len > 0) {
+102 -2
View File
@@ -1,5 +1,5 @@
/* iksemel (XML parser for Jabber)
** Copyright (C) 2000-2004 Gurer Ozen <madcat@e-kolay.net>
** 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.
*/
@@ -183,6 +183,106 @@ iks_insert_node (iks *x, iks *y)
return y;
}
iks *
iks_append (iks *x, const char *name)
{
iks *y;
if (!x) return NULL;
y = iks_new_within (name, x->s);
if (!y) return NULL;
if (x->next) {
x->next->prev = y;
} else {
IKS_TAG_LAST_CHILD (x->parent) = y;
}
y->next = x->next;
x->next = y;
y->parent = x->parent;
y->prev = x;
return y;
}
iks *
iks_prepend (iks *x, const char *name)
{
iks *y;
if (!x) return NULL;
y = iks_new_within (name, x->s);
if (!y) return NULL;
if (x->prev) {
x->prev->next = y;
} else {
IKS_TAG_CHILDREN (x->parent) = y;
}
y->prev = x->prev;
x->prev = y;
y->parent = x->parent;
y->next = x;
return y;
}
iks *
iks_append_cdata (iks *x, const char *data, size_t len)
{
iks *y;
if (!x || !data) return NULL;
if (len == 0) len = strlen (data);
y = iks_new_within (NULL, x->s);
if (!y) return NULL;
y->type = IKS_CDATA;
IKS_CDATA_CDATA (y) = iks_stack_strdup (x->s, data, len);
if (!IKS_CDATA_CDATA (y)) return NULL;
IKS_CDATA_LEN (y) = len;
if (x->next) {
x->next->prev = y;
} else {
IKS_TAG_LAST_CHILD (x->parent) = y;
}
y->next = x->next;
x->next = y;
y->parent = x->parent;
y->prev = x;
return y;
}
iks *
iks_prepend_cdata (iks *x, const char *data, size_t len)
{
iks *y;
if (!x || !data) return NULL;
if (len == 0) len = strlen (data);
y = iks_new_within (NULL, x->s);
if (!y) return NULL;
y->type = IKS_CDATA;
IKS_CDATA_CDATA(y) = iks_stack_strdup (x->s, data, len);
if (!IKS_CDATA_CDATA (y)) return NULL;
IKS_CDATA_LEN (y) = len;
if (x->prev) {
x->prev->next = y;
} else {
IKS_TAG_CHILDREN (x->parent) = y;
}
y->prev = x->prev;
x->prev = y;
y->parent = x->parent;
y->next = x;
return y;
}
void
iks_hide (iks *x)
{
@@ -379,7 +479,7 @@ char *
iks_name (iks *x)
{
if (x) {
if (IKS_TAG == x->type)
if (IKS_TAG == x->type)
return IKS_TAG_NAME (x);
else
return IKS_ATTRIB_NAME (x);
+2 -2
View File
@@ -192,10 +192,11 @@ iks_stack_delete (ikstack **sp)
}
s = *sp;
if (!s) {
return;
}
*sp = NULL;
c = s->meta->next;
while (c) {
@@ -210,5 +211,4 @@ iks_stack_delete (ikstack **sp)
c = tmp;
}
iks_free (s);
}
+12 -6
View File
@@ -36,6 +36,7 @@ io_connect (iksparser *prs, void **socketptr, const char *server, int port)
struct addrinfo hints;
struct addrinfo *addr_res, *addr_ptr;
char port_str[6];
int err = 0;
hints.ai_flags = AI_CANONNAME;
hints.ai_family = PF_UNSPEC;
@@ -52,14 +53,20 @@ io_connect (iksparser *prs, void **socketptr, const char *server, int port)
addr_ptr = addr_res;
while (addr_ptr) {
err = IKS_NET_NOSOCK;
sock = socket (addr_ptr->ai_family, addr_ptr->ai_socktype, addr_ptr->ai_protocol);
if (sock != -1) break;
if (sock != -1) {
err = IKS_NET_NOCONN;
tmp = connect (sock, addr_ptr->ai_addr, addr_ptr->ai_addrlen);
if (tmp == 0) break;
io_close ((void *) sock);
sock = -1;
}
addr_ptr = addr_ptr->ai_next;
}
if (sock == -1) return IKS_NET_NOSOCK;
tmp = connect (sock, addr_ptr->ai_addr, addr_ptr->ai_addrlen);
freeaddrinfo (addr_res);
if (sock == -1) return err;
#else
struct hostent *host;
struct sockaddr_in sin;
@@ -74,11 +81,11 @@ io_connect (iksparser *prs, void **socketptr, const char *server, int port)
if (sock == -1) return IKS_NET_NOSOCK;
tmp = connect (sock, (struct sockaddr *)&sin, sizeof (struct sockaddr_in));
#endif
if (tmp != 0) {
io_close ((void *) sock);
return IKS_NET_NOCONN;
}
#endif
*socketptr = (void *) sock;
@@ -135,7 +142,6 @@ io_recv (void *socket, char *buffer, size_t buf_len, int timeout)
}
t++;
}
}
}
+2 -2
View File
@@ -173,8 +173,8 @@ iks_make_auth (iksid *id, const char *pass, const char *sid)
char buf[41];
iksha *sha;
sha = iks_sha_new ();
iks_sha_hash (sha, sid, strlen (sid), 0);
iks_sha_hash (sha, pass, strlen (pass), 1);
iks_sha_hash (sha, (const unsigned char*)sid, strlen (sid), 0);
iks_sha_hash (sha, (const unsigned char*)pass, strlen (pass), 1);
iks_sha_print (sha, buf);
iks_sha_delete (sha);
iks_insert_cdata (iks_insert (y, "digest"), buf, 40);
+2 -2
View File
@@ -43,7 +43,7 @@ struct iksmd5_struct {
unsigned char blen;
};
static unsigned long int T[] =
static const unsigned long int T[] =
{ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
@@ -151,7 +151,7 @@ void iks_md5(const char *data, char *buf)
{
iksmd5 *md5 = iks_md5_new();
iks_md5_hash(md5, data, strlen(data), 1);
iks_md5_hash(md5, (const unsigned char*)data, strlen(data), 1);
iks_md5_print(md5, buf);
iks_md5_delete(md5);
}
+2 -1
View File
@@ -149,7 +149,8 @@ stack_expand (iksparser *prs, int len)
if (need < prs->stack_max) {
need = prs->stack_max * 2;
} else {
need = prs->stack_max + (need * 1.2);
/* need x 1.2 for integer only archs like ARM */
need = prs->stack_max + ( (need * 6) / 5);
}
tmp = iks_malloc (need);
if (!tmp) return 0;
+16 -16
View File
@@ -11,10 +11,10 @@ static void sha_buffer (iksha *sha, const unsigned char *data, int len);
static void sha_calculate (iksha *sha);
struct iksha_struct {
unsigned long hash[5];
unsigned long buf[80];
unsigned int hash[5];
unsigned int buf[80];
int blen;
unsigned long lenhi, lenlo;
unsigned int lenhi, lenlo;
};
iksha *
@@ -32,11 +32,11 @@ void
iks_sha_reset (iksha *sha)
{
memset (sha, 0, sizeof (iksha));
sha->hash[0] = 0x67452301L;
sha->hash[1] = 0xefcdab89L;
sha->hash[2] = 0x98badcfeL;
sha->hash[3] = 0x10325476L;
sha->hash[4] = 0xc3d2e1f0L;
sha->hash[0] = 0x67452301;
sha->hash[1] = 0xefcdab89;
sha->hash[2] = 0x98badcfe;
sha->hash[3] = 0x10325476;
sha->hash[4] = 0xc3d2e1f0;
}
void
@@ -74,7 +74,7 @@ iks_sha_print (iksha *sha, char *hash)
for (i=0; i<5; i++)
{
sprintf (hash, "%08lx", sha->hash[i]);
sprintf (hash, "%08x", sha->hash[i]);
hash += 8;
}
}
@@ -91,7 +91,7 @@ iks_sha (const char *data, char *hash)
iksha *sha;
sha = iks_sha_new ();
iks_sha_hash (sha, data, strlen (data), 1);
iks_sha_hash (sha, (const unsigned char*)data, strlen (data), 1);
iks_sha_print (sha, hash);
iks_free (sha);
}
@@ -103,7 +103,7 @@ sha_buffer (iksha *sha, const unsigned char *data, int len)
for (i=0; i<len; i++) {
sha->buf[sha->blen / 4] <<= 8;
sha->buf[sha->blen / 4] |= (unsigned long)data[i];
sha->buf[sha->blen / 4] |= (unsigned int)data[i];
if ((++sha->blen) % 64 == 0) {
sha_calculate (sha);
sha->blen = 0;
@@ -128,7 +128,7 @@ static void
sha_calculate (iksha *sha)
{
int i;
unsigned long A, B, C, D, E, TMP;
unsigned int A, B, C, D, E, TMP;
for (i=16; i<80; i++)
sha->buf[i] = SRL (sha->buf[i-3] ^ sha->buf[i-8] ^ sha->buf[i-14] ^ sha->buf[i-16], 1);
@@ -139,10 +139,10 @@ sha_calculate (iksha *sha)
D = sha->hash[3];
E = sha->hash[4];
SHA (0, 19, ((C^D)&B)^D, 0x5a827999L);
SHA (20, 39, B^C^D, 0x6ed9eba1L);
SHA (40, 59, (B&C)|(D&(B|C)), 0x8f1bbcdcL);
SHA (60, 79, B^C^D, 0xca62c1d6L);
SHA (0, 19, ((C^D)&B)^D, 0x5a827999);
SHA (20, 39, B^C^D, 0x6ed9eba1);
SHA (40, 59, (B&C)|(D&(B|C)), 0x8f1bbcdc);
SHA (60, 79, B^C^D, 0xca62c1d6);
sha->hash[0] += A;
sha->hash[1] += B;
+124 -87
View File
@@ -1,5 +1,5 @@
/* iksemel (XML parser for Jabber)
** Copyright (C) 2000-2004 Gurer Ozen <madcat@e-kolay.net>
** 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.
*/
@@ -122,106 +122,143 @@ insert_attribs (iks *x, char **atts)
#define CNONCE_LEN 4
static void
iks_sasl_challenge (struct stream_data *data, iks *challenge)
parse_digest (char *message, const char *key, char **value_ptr, char **value_end_ptr)
{
char *b;
iks *x;
char *t;
b = iks_cdata (iks_child (challenge));
if (!b) return;
*value_ptr = NULL;
*value_end_ptr = NULL;
b = iks_base64_decode (b);
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;
}
}
}
if (strstr (b, "rspauth")) {
x = iks_new("response");
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 {
char *realm, *nonce, *charset = NULL, *algorithm = NULL;
char *realm_end, *nonce_end, cnonce[CNONCE_LEN*8 + 1];
unsigned char a1_h[16], a1[33], a2[33], response_value[33];
char *response, *response_coded;
iksmd5 *md5;
int i;
realm = (char *) data->server;
}
realm = strstr (b, "realm");
if (realm) {
realm += 7;
do {
realm_end = strchr(realm, '"');
} while (*(realm_end - 1) == '\\');
} else {
realm_end = 0;
realm = (char *) data->server;
}
nonce = strstr (b, "nonce");
if (nonce) {
nonce += 7;
do {
nonce_end = strchr (nonce, '"');
} while (*(nonce - 1) == '\\');
} else {
iks_free (b);
return;
}
charset = strstr (b, "charset");
if (charset) charset += 8;
algorithm = strstr (b, "algorithm");
if (algorithm) algorithm += 10;
if (realm_end) *realm_end = 0;
*nonce_end = 0;
/* generate random client challenge */
for (i = 0; i < CNONCE_LEN; ++i)
sprintf (cnonce + i*8, "%08x", rand());
for (i = 0; i < CNONCE_LEN; ++i)
sprintf (cnonce + i*8, "%08x", rand());
md5 = iks_md5_new();
if (!md5) return NULL;
md5 = iks_md5_new();
iks_md5_hash (md5, data->auth_username, iks_strlen (data->auth_username), 0);
iks_md5_hash (md5, ":", 1, 0);
iks_md5_hash (md5, realm, iks_strlen (realm), 0);
iks_md5_hash (md5, ":", 1, 0);
iks_md5_hash (md5, data->auth_pass, iks_strlen (data->auth_pass), 1);
iks_md5_digest (md5, a1_h);
iks_md5_reset (md5);
iks_md5_hash (md5, a1_h, 16, 0);
iks_md5_hash (md5, ":", 1, 0);
iks_md5_hash (md5, nonce, iks_strlen (nonce), 0);
iks_md5_hash (md5, ":", 1, 0);
iks_md5_hash (md5, cnonce, iks_strlen (cnonce), 1);
iks_md5_print (md5, a1);
iks_md5_reset (md5);
iks_md5_hash (md5, "AUTHENTICATE:xmpp/", 18, 0);
iks_md5_hash (md5, data->server, iks_strlen (data->server), 1);
iks_md5_print (md5, a2);
iks_md5_reset (md5);
iks_md5_hash (md5, a1, 32, 0);
iks_md5_hash (md5, ":", 1, 0);
iks_md5_hash (md5, nonce, iks_strlen (nonce), 0);
iks_md5_hash (md5, ":00000001:", 10, 0);
iks_md5_hash (md5, cnonce, iks_strlen (cnonce), 0);
iks_md5_hash (md5, ":auth:", 6, 0);
iks_md5_hash (md5, a2, 32, 1);
iks_md5_print (md5, response_value);
iks_md5_delete (md5);
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);
i = iks_strlen (data->auth_username) + iks_strlen (realm) +
iks_strlen (nonce) + iks_strlen (data->server) +
CNONCE_LEN*8 + 136;
response = iks_malloc (i);
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);
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);
iks_free (response_coded);
}
iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL);
iks_send (data->prs, x);
iks_delete (x);
iks_free (b);
iks_free (response);
return x;
}
static void
iks_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 int