Exemplo n.º 1
0
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;
	}
	case IKS_SASL_OAUTH_2:
	{
		int len = iks_strlen(username) + iks_strlen(pass) + 2;
		char *s = iks_malloc(80 + len);
		char *base64;

		iks_insert_attrib(x, "mechanism", "X-OAUTH2");
		iks_insert_attrib(x, "auth:service", "oauth2");
		iks_insert_attrib(x, "xmlns:auth", "http://www.google.com/talk/protocol/auth");

		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;
	}
	default:
		iks_delete(x);
		return IKS_NET_NOTSUPP;
	}
	iks_send(prs, x);
	iks_delete(x);
	return IKS_OK;
}
Exemplo n.º 2
0
ikstack *
iks_stack_new (size_t meta_chunk, size_t data_chunk)
{
	ikstack *s;
	size_t len;

	if (meta_chunk < MIN_CHUNK_SIZE) meta_chunk = MIN_CHUNK_SIZE;
	if (meta_chunk & ALIGN_MASK) meta_chunk = ALIGN (meta_chunk);
	if (data_chunk < MIN_CHUNK_SIZE) data_chunk = MIN_CHUNK_SIZE;
	if (data_chunk & ALIGN_MASK) data_chunk = ALIGN (data_chunk);

	len = sizeof (ikstack) + meta_chunk + data_chunk + (sizeof (ikschunk) * 2);
	s = iks_malloc (len);
	if (!s) return NULL;
	s->allocated = len;
	s->meta = (ikschunk *) ((char *) s + sizeof (ikstack));
	s->meta->next = NULL;
	s->meta->size = meta_chunk;
	s->meta->used = 0;
	s->meta->last = (size_t) -1;
	s->data = (ikschunk *) ((char *) s + sizeof (ikstack) + sizeof (ikschunk) + meta_chunk);
	s->data->next = NULL;
	s->data->size = data_chunk;
	s->data->used = 0;
	s->data->last = (size_t) -1;
	return s;
}
Exemplo n.º 3
0
static int
stack_expand (iksparser *prs, int len)
{
	size_t need;
	off_t diff;
	char *tmp;
	need = len - (prs->stack_max - prs->stack_pos);
	if (need < prs->stack_max) {
		need = prs->stack_max * 2;
	} else {
		/* 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;
	diff = tmp - prs->stack;
	memcpy (tmp, prs->stack, prs->stack_max);
	iks_free (prs->stack);
	prs->stack = tmp;
	prs->stack_max = need;
	prs->tag_name += diff;
	if (prs->attflag != 0) {
		int i = 0;
		while ((unsigned)i < (prs->attmax * 2)) {
			if (prs->atts[i]) prs->atts[i] += diff;
			i++;
		}
	}
	return 1;
}
Exemplo n.º 4
0
static int
tls_handshake (struct ikstls_data **datap, ikstransport *trans, void *sock)
{
	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 };
	struct ikstls_data *data;
	int ret;

	*datap = NULL;

	data = iks_malloc (sizeof(*data));
	if (!data) return IKS_NOMEM;
	memset (data, 0, sizeof(*data));
	data->trans = trans;
	data->sock = sock;
	data->timeout = -1;

	if (gnutls_global_init () != 0) {
		iks_free (data);
		return IKS_NOMEM;
	}

	if (gnutls_certificate_allocate_credentials (&data->cred) < 0) {
		iks_free (data);
		return IKS_NOMEM;
	}

	if (gnutls_init (&data->sess, GNUTLS_CLIENT) != 0) {
		gnutls_certificate_free_credentials (data->cred);
		iks_free (data);
		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);

	ret = gnutls_handshake (data->sess);
	if (ret != 0) {
		gnutls_deinit (data->sess);
		gnutls_certificate_free_credentials (data->cred);
		iks_free (data);
		return IKS_NET_TLSFAIL;
	}

	*datap = data;
	return IKS_OK;
}
Exemplo n.º 5
0
static int
stack_init (iksparser *prs)
{
	prs->stack = iks_malloc (128);
	if (!prs->stack) return 0;
	prs->stack_max = 128;
	prs->stack_pos = 0;
	return 1;
}
Exemplo n.º 6
0
iksmd5 *iks_md5_new(void)
{
	iksmd5 *md5 = iks_malloc(sizeof(iksmd5));

	if (!md5)
		return NULL;
	iks_md5_reset(md5);
	return md5;
}
Exemplo n.º 7
0
char *iks_urlencode_new(const char *s)
{
	int len = iks_urlencode_len(s) + 1;
	char *res;

	if((res = iks_malloc(len)))
	{
		iks_urlencode_copy(s, res);
		res[len] = 0x00;
	}
	return res;
}
Exemplo n.º 8
0
iksparser *
iks_sax_new (void *user_data, iksTagHook *tagHook, iksCDataHook *cdataHook)
{
	iksparser *prs;

	prs = iks_malloc (sizeof (iksparser));
	if (NULL == prs) return NULL;
	memset (prs, 0, sizeof (iksparser));
	prs->user_data = user_data;
	prs->tagHook = tagHook;
	prs->cdataHook = cdataHook;
	return prs;
}
Exemplo n.º 9
0
Arquivo: base64.c Projeto: e6/iksemel
char *iks_base64_decode(const char *buf)
{
    char *res, *save;
    char val;
    const char *foo;
    const char *end;
    int index;
    size_t len;

    if (!buf)
        return NULL;

    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) {
        if (!(foo = strchr(base64_charset, *buf)))
            foo = base64_charset;
        val = (int)(foo - base64_charset);
        buf++;
        switch (index) {
        case 0:
            *res |= val << 2;
            break;
        case 1:
            *res++ |= val >> 4;
            *res |= val << 4;
            break;
        case 2:
            *res++ |= val >> 2;
            *res |= val << 6;
            break;
        case 3:
            *res++ |= val;
            break;
        }
        index++;
        index %= 4;
    }
    *res = 0;

    return save;
}
Exemplo n.º 10
0
int iks_send_header(iksparser *prs, const char *to)
{
	struct stream_data *data = iks_user_data(prs);
	char *msg;
	int len, err;

	len = 91 + strlen(data->name_space) + 6 + strlen(to) + 16 + 1;
	msg = iks_malloc(len);
	if(!msg) return IKS_NOMEM;
	sprintf(msg, "<?xml version='1.0'?>"
	        "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='"
	        "%s' to='%s' version='1.0'>", data->name_space, to);
	err = iks_send_raw(prs, msg);
	iks_free(msg);
	if(err) return err;
	data->server = to;
	return IKS_OK;
}
Exemplo n.º 11
0
// In the mainline version this function took "to" as an argument, but
// are we not always talking to self->server?
int
ikss_Stream_send_header (ikss_Stream *self)
{
  char *msg;
  int len, err;
  const char *to = self->server;

  len = 91 + strlen (self->name_space) + 6 + strlen (to) + 16 + 1;
  msg = iks_malloc (len);
  if (!msg) return IKS_NOMEM;
  // We are XMPP compliant, and hence sending a version number, too.
  // Note that "jabberd" is not compliant in this sense.
  sprintf (msg, "<?xml version='1.0'?>"
	   "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='"
	   "%s' to='%s' version='1.0'>", self->name_space, to);
  err = ikss_Stream_send_raw (self, msg);
  if (err) return err;
  return IKS_OK;
}
Exemplo n.º 12
0
char *iks_base64_encode(const char *buf, int len)
{
	char *res, *save;
	int k, t;

	if (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];
		t = ((*buf & 0x03) << 4);
		buf++;
		*res++ = base64_charset[t | (*buf >> 4)];
		t = ((*buf & 0x0F) << 2);
		buf++;
		*res++ = base64_charset[t | (*buf >> 6)];
		*res++ = base64_charset[*buf++ & 0x3F];
	}

	switch (len % 3) {
		case 2:
			*res++ = base64_charset[*buf >> 2];
			t =  ((*buf & 0x03) << 4);
			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 = 0;
	return save;
}
Exemplo n.º 13
0
static ikschunk *
find_space (ikstack *s, ikschunk *c, size_t size)
{
	/* FIXME: dont use *2 after over allocated chunks */
	while (1) {
		if (c->size - c->used >= size) return c;
		if (!c->next) {
			if ((c->size * 2) > size) size = c->size * 2;
			c->next = iks_malloc (sizeof (ikschunk) + size);
			if (!c->next) return NULL;
			s->allocated += sizeof (ikschunk) + size;
			c = c->next;
			c->next = NULL;
			c->size = size;
			c->used = 0;
			c->last = (size_t) -1;
			return c;
		}
		c = c->next;
	}
	return NULL;
}
Exemplo n.º 14
0
// Takes ownership of "xmlstr", unconditionally. Do NOT pass in any
// string allocated from an iks_stack, as mallocing is assumed.
int
ikss_Stream_send_raw (ikss_Stream *self, char *xmlstr)
{
#if !defined(__SYMBIAN32__)
  printf("SEND '%s'\n", xmlstr);
#endif /* __SYMBIAN32__ */

  if (ikst_IsSendActive(self->sock)) {
    // Not allowed to do another send, just buffer the data.
    if (self->send_more_buf) {
      char* newbuf = iks_malloc(strlen(self->send_more_buf) + strlen(xmlstr) + 1);
      if (!newbuf) return IKS_NOMEM;
      strcpy(newbuf, self->send_more_buf);
      strcat(newbuf, xmlstr);
      free(xmlstr);
      free(self->send_more_buf);
      self->send_more_buf = newbuf;
    } else {
      self->send_more_buf = xmlstr;
    }
    return 0;
  }

  resetSendBuf(self);

  int len = strlen(xmlstr);
  
  int ret = ikst_Send (self->sock, xmlstr, len);
  if (ret) {
    free(xmlstr);
    return ret;
  } else {
    self->send_buf = xmlstr;
    self->send_len = len;
    self->send_count = 0;
    return IKS_OK;
  }
}
Exemplo n.º 15
0
// if returns IKS_OK, do not send more before ikss_SENT callback
int
ikss_Stream_start_sasl (ikss_Stream *self, enum ikssasltype type, 
			const char *username, const char *pass)
{
  iks *x;

  x = iks_new ("auth"); // xxx check return?
  iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL); // xxx check return?
  switch (type) {
  case IKS_SASL_PLAIN: {
    int len = iks_strlen (username) + iks_strlen (pass) + 2;
    char *s = iks_malloc (80+len); // xxx check for oom, on error free x and return error code
    char *base64;

    iks_insert_attrib (x, "mechanism", "PLAIN"); // xxx check return?
    sprintf (s, "%c%s%c%s", 0, username, 0, pass);
    base64 = iks_base64_encode (s, len); // xxx check return?
    iks_insert_cdata (x, base64, 0);
    iks_free (base64);
    iks_free (s);
    break;
  }
  case IKS_SASL_DIGEST_MD5: {
    iks_insert_attrib (x, "mechanism", "DIGEST-MD5"); // xxx check return?
    self->auth_username = username;
    self->auth_pass = pass;
    break;
  }
  default:
    iks_delete (x);
    return IKS_NET_NOTSUPP;
  }
  int ret = ikss_Stream_send_node (self, x);
  iks_delete (x); // delete ok since above makes a copy
  if (ret) return ret;
  return IKS_OK;
}
Exemplo n.º 16
0
static enum ikserror
sax_core (iksparser *prs, char *buf, int len)
{
	enum ikserror err;
	int pos = 0, old = 0, re, stack_old = -1;
	unsigned char c;

	while (pos < len) {
		re = 0;
		c = buf[pos];
		if (0 == c || 0xFE == c || 0xFF == c) return IKS_BADXML;
		if (prs->uni_max) {
			if ((c & 0xC0) != 0x80) return IKS_BADXML;
			prs->uni_char <<= 6;
			prs->uni_char += (c & 0x3f);
			prs->uni_len++;
			if (prs->uni_len == prs->uni_max) {
				/* Security check: avoid overlong sequences */
				if (prs->uni_max == 2 && prs->uni_char < 0x80)
					return IKS_BADXML;
				if (prs->uni_max == 3 && prs->uni_char < 0x7FF)
					return IKS_BADXML;
				if (prs->uni_max == 4 && prs->uni_char < 0xffff)
					return IKS_BADXML;
				if (prs->uni_max == 5 && prs->uni_char < 0x1fffff)
					return IKS_BADXML;
				if (prs->uni_max == 6 && prs->uni_char < 0x3ffffff)
					return IKS_BADXML;
				prs->uni_max = 0;
				prs->uni_char = 0;
			}
			goto cont;
		} else {
			if (c & 0x80) {
				unsigned char mask;
				if ((c & 0x60) == 0x40) {
					prs->uni_max = 2;
					mask = 0x1F;
				} else if ((c & 0x70) == 0x60) {
					prs->uni_max = 3;
					mask = 0x0F;
				} else if ((c & 0x78) == 0x70) {
					prs->uni_max = 4;
					mask = 0x07;
				} else if ((c & 0x7C) == 0x78) {
					prs->uni_max = 5;
					mask = 0x03;
				} else if ((c & 0x7E) == 0x7C) {
					prs->uni_max = 6;
					mask = 0x01;
				} else {
					return IKS_BADXML;
				}
				prs->uni_char = c & mask;
				prs->uni_len = 1;
				if (stack_old == -1
					&& (prs->context == C_TAG
						|| prs->context == C_ATTRIBUTE_1
						|| prs->context == C_VALUE_APOS
						|| prs->context == C_VALUE_QUOT)) stack_old = pos;
				goto cont;
			}
		}

		switch (prs->context) {
			case C_CDATA:
				if ('&' == c) {
					if (old < pos && prs->cdataHook) {
						err = prs->cdataHook (prs->user_data, &buf[old], pos - old);
						if (IKS_OK != err) return err;
					}
					prs->context = C_ENTITY;
					prs->entpos = 0;
					break;
				}
				if ('<' == c) {
					if (old < pos && prs->cdataHook) {
						err = prs->cdataHook (prs->user_data, &buf[old], pos - old);
						if (IKS_OK != err) return err;
					}
					STACK_INIT;
					prs->tag_name = STACK_PUSH_START;
					if (!prs->tag_name) return IKS_NOMEM;
					prs->context = C_TAG_START;
				}
				break;

			case C_TAG_START:
				prs->context = C_TAG;
				if ('/' == c) {
					prs->tagtype = IKS_CLOSE;
					break;
				}
				if ('?' == c) {
					prs->context = C_PI;
					break;
				}
				if ('!' == c) {
					prs->context = C_MARKUP;
					break;
				}
				prs->tagtype = IKS_OPEN;
				stack_old = pos;
				break;

			case C_TAG:
				if (IS_WHITESPACE(c)) {
					if (IKS_CLOSE == prs->tagtype)
						prs->oldcontext = C_TAG_END;
					else
						prs->oldcontext = C_ATTRIBUTE;
					prs->context = C_WHITESPACE;
					if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
					stack_old = -1;
					STACK_PUSH_END;
					break;
				}
				if ('/' == c) {
					if (IKS_CLOSE == prs->tagtype) return IKS_BADXML;
					prs->tagtype = IKS_SINGLE;
					prs->context = C_TAG_END;
					if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
					stack_old = -1;
					STACK_PUSH_END;
					break;
				}
				if ('>' == c) {
					prs->context = C_TAG_END;
					if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
					stack_old = -1;
					STACK_PUSH_END;
					re = 1;
					break;
				}
				if (stack_old == -1) stack_old = pos;
				break;

			case C_TAG_END:
				if (c != '>') return IKS_BADXML;
				if (prs->tagHook) {
					char **tmp;
					if (prs->attcur == 0) tmp = NULL; else tmp = prs->atts;
					err = prs->tagHook (prs->user_data, prs->tag_name, tmp, prs->tagtype);
					if (IKS_OK != err) return err;
				}
				prs->stack_pos = 0;
				stack_old = -1;
				prs->attcur = 0;
				prs->attflag = 0;
				prs->context = C_CDATA;
				old = pos + 1;
				break;

			case C_ATTRIBUTE:
				if ('/' == c) {
					prs->tagtype = IKS_SINGLE;
					prs->context = C_TAG_END;
					break;
				}
				if ('>' == c) {
					prs->context = C_TAG_END;
					re = 1;
					break;
				}
				if (!prs->atts) {
					prs->attmax = 12;
					prs->atts = iks_malloc (sizeof(char *) * 2 * 12);
					if (!prs->atts) return IKS_NOMEM;
					memset (prs->atts, 0, sizeof(char *) * 2 * 12);
					prs->attcur = 0;
				} else {
					if (prs->attcur >= ((prs->attmax - 1) * 2)) {
						void *tmp;
						prs->attmax += 12;
						tmp = iks_malloc (sizeof(char *) * 2 * prs->attmax);
						if (!tmp) return IKS_NOMEM;
						memset (tmp, 0, sizeof(char *) * 2 * prs->attmax);
						memcpy (tmp, prs->atts, sizeof(char *) * prs->attcur);
						free (prs->atts);
						prs->atts = tmp;
					}
				}
				prs->attflag = 1;
				prs->atts[prs->attcur] = STACK_PUSH_START;
				stack_old = pos;
				prs->context = C_ATTRIBUTE_1;
				break;

			case C_ATTRIBUTE_1:
				if ('=' == c) {
					if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
					stack_old = -1;
					STACK_PUSH_END;
					prs->context = C_VALUE;
					break;
				}
				if (IS_WHITESPACE(c)) {
					if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
					stack_old = -1;
					STACK_PUSH_END;
					prs->oldcontext = C_ATTRIBUTE_1;
					prs->context = C_WHITESPACE;
					break;
				}
				if (stack_old == -1) stack_old = pos;
				break;

			case C_ATTRIBUTE_2:
				if ('/' == c) {
					prs->tagtype = IKS_SINGLE;
					prs->atts[prs->attcur] = NULL;
					prs->context = C_TAG_END;
					break;
				}
				if ('>' == c) {
					prs->atts[prs->attcur] = NULL;
					prs->context = C_TAG_END;
					re = 1;
					break;
				}
				prs->context = C_ATTRIBUTE;
				re = 1;
				break;

			case C_VALUE:
				if (IS_WHITESPACE(c)) break;
				prs->atts[prs->attcur + 1] = STACK_PUSH_START;
				if ('\'' == c) {
					prs->context = C_VALUE_APOS;
					break;
				}
				if ('"' == c) {
					prs->context = C_VALUE_QUOT;
					break;
				}
				return IKS_BADXML;

			case C_VALUE_APOS:
				if ('\'' == c) {
					if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
					stack_old = -1;
					STACK_PUSH_END;
					prs->oldcontext = C_ATTRIBUTE_2;
					prs->context = C_WHITESPACE;
					prs->attcur += 2;
				}
				if (stack_old == -1) stack_old = pos;
				break;

			case C_VALUE_QUOT:
				if ('"' == c) {
					if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old);
					stack_old = -1;
					STACK_PUSH_END;
					prs->oldcontext = C_ATTRIBUTE_2;
					prs->context = C_WHITESPACE;
					prs->attcur += 2;
				}
				if (stack_old == -1) stack_old = pos;
				break;

			case C_WHITESPACE:
				if (NOT_WHITESPACE(c)) {
					prs->context = prs->oldcontext;
					re = 1;
				}
				break;

			case C_ENTITY:
				if (';' == c) {
					char hede[2];
					char t = '?';
					prs->entity[prs->entpos] = '\0';
					if (strcmp(prs->entity, "amp") == 0)
						t = '&';
					else if (strcmp(prs->entity, "quot") == 0)
						t = '"';
					else if (strcmp(prs->entity, "apos") == 0)
						t = '\'';
					else if (strcmp(prs->entity, "lt") == 0)
						t = '<';
					else if (strcmp(prs->entity, "gt") == 0)
						t = '>';
					old = pos + 1;
					hede[0] = t;
					if (prs->cdataHook) {
						err = prs->cdataHook (prs->user_data, &hede[0], 1);
						if (IKS_OK != err) return err;
					}
					prs->context = C_CDATA;
				} else {
					prs->entity[prs->entpos++] = buf[pos];
					if (prs->entpos > 7) return IKS_BADXML;
				}
				break;

			case C_COMMENT:
				if ('-' != c) return IKS_BADXML;
				prs->context = C_COMMENT_1;
				break;

			case C_COMMENT_1:
				if ('-' == c) prs->context = C_COMMENT_2;
				break;

			case C_COMMENT_2:
				if ('-' == c)
					prs->context = C_COMMENT_3;
				else
					prs->context = C_COMMENT_1;
				break;

			case C_COMMENT_3:
				if ('>' != c) return IKS_BADXML;
				prs->context = C_CDATA;
				old = pos + 1;
				break;

			case C_MARKUP:
				if ('[' == c) {
					prs->context = C_SECT;
					break;
				}
				if ('-' == c) {
					prs->context = C_COMMENT;
					break;
				}
				prs->context = C_MARKUP_1;

			case C_MARKUP_1:
				if ('>' == c) {
					old = pos + 1;
					prs->context = C_CDATA;
				}
				break;

			case C_SECT:
				if ('C' == c) {
					prs->context = C_SECT_CDATA;
					break;
				}
				return IKS_BADXML;

			case C_SECT_CDATA:
				if ('D' != c) return IKS_BADXML;
				prs->context = C_SECT_CDATA_1;
				break;

			case C_SECT_CDATA_1:
				if ('A' != c) return IKS_BADXML;
				prs->context = C_SECT_CDATA_2;
				break;

			case C_SECT_CDATA_2:
				if ('T' != c) return IKS_BADXML;
				prs->context = C_SECT_CDATA_3;
				break;

			case C_SECT_CDATA_3:
				if ('A' != c) return IKS_BADXML;
				prs->context = C_SECT_CDATA_4;
				break;

			case C_SECT_CDATA_4:
				if ('[' != c) return IKS_BADXML;
				old = pos + 1;
				prs->context = C_SECT_CDATA_C;
				break;

			case C_SECT_CDATA_C:
				if (']' == c) {
					prs->context = C_SECT_CDATA_E;
					if (prs->cdataHook && old < pos) {
						err = prs->cdataHook (prs->user_data, &buf[old], pos - old);
						if (IKS_OK != err) return err;
					}
				}
				break;

			case C_SECT_CDATA_E:
				if (']' == c) {
					prs->context = C_SECT_CDATA_E2;
				} else {
					if (prs->cdataHook) {
						err = prs->cdataHook (prs->user_data, "]", 1);
						if (IKS_OK != err) return err;
					}
					old = pos;
					prs->context = C_SECT_CDATA_C;
				}
				break;

			case C_SECT_CDATA_E2:
				if ('>' == c) {
					old = pos + 1;
					prs->context = C_CDATA;
				} else {
					if (prs->cdataHook) {
						err = prs->cdataHook (prs->user_data, "]]", 2);
						if (IKS_OK != err) return err;
					}
					old = pos;
					prs->context = C_SECT_CDATA_C;
				}
				break;

			case C_PI:
				old = pos + 1;
				if ('>' == c) prs->context = C_CDATA;
				break;
		}
cont:
		if (0 == re) {
			pos++;
			prs->nr_bytes++;
			if ('\n' == c) prs->nr_lines++;
		}
	}

	if (stack_old != -1)
		STACK_PUSH (buf + stack_old, pos - stack_old);

	err = IKS_OK;
	if (prs->cdataHook && (prs->context == C_CDATA || prs->context == C_SECT_CDATA_C) && old < pos)
		err = prs->cdataHook (prs->user_data, &buf[old], pos - old);
	return err;
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
// Note that "s" may be NULL, in which case strings are not allocated
// from the stack, and in which case the caller is responsible for
// freeing any returned string.
char *
iks_string (ikstack *s, iks *x)
{
	size_t size;
	int level, dir;
	iks *y, *z;
	char *ret, *t;

	if (!x) return NULL;

	if (x->type == IKS_CDATA) {
		if (s) {
			return iks_stack_strdup (s, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x));
		} else {
			ret = iks_malloc (IKS_CDATA_LEN (x));
			memcpy (ret, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x));
			return ret;
		}
	}

	size = 0;
	level = 0;
	dir = 0;
	y = x;
	while (1) {
		if (dir==0) {
			if (y->type == IKS_TAG) {
				size++;
				size += strlen (IKS_TAG_NAME (y));
				for (z = IKS_TAG_ATTRIBS (y); z; z = z->next) {
					size += 4 + strlen (IKS_ATTRIB_NAME (z))
						+ escape_size (IKS_ATTRIB_VALUE (z), strlen (IKS_ATTRIB_VALUE (z)));
				}
				if (IKS_TAG_CHILDREN (y)) {
					size++;
					y = IKS_TAG_CHILDREN (y);
					level++;
					continue;
				} else {
					size += 2;
				}
			} else {
				size += escape_size (IKS_CDATA_CDATA (y), IKS_CDATA_LEN (y));
			}
		}
		z = y->next;
		if (z) {
			if (0 == level) {
				if (IKS_TAG_CHILDREN (y)) size += 3 + strlen (IKS_TAG_NAME (y));
				break;
			}
			y = z;
			dir = 0;
		} else {
			y = y->parent;
			level--;
			if (level >= 0) size += 3 + strlen (IKS_TAG_NAME (y));
			if (level < 1) break;
			dir = 1;
		}
	}

	if (s) ret = iks_stack_alloc (s, size + 1);
	else ret = iks_malloc (size + 1);

	if (!ret) return NULL;

	t = ret;
	level = 0;
	dir = 0;
	while (1) {
		if (dir==0) {
			if (x->type == IKS_TAG) {
				*t++ = '<';
				t = my_strcat (t, IKS_TAG_NAME (x), 0);
				y = IKS_TAG_ATTRIBS (x);
				while (y) {
					*t++ = ' ';
					t = my_strcat (t, IKS_ATTRIB_NAME (y), 0);
					*t++ = '=';
					*t++ = '\'';
					t = escape (t, IKS_ATTRIB_VALUE (y), strlen (IKS_ATTRIB_VALUE (y)));
					*t++ = '\'';
					y = y->next;
				}
				if (IKS_TAG_CHILDREN (x)) {
					*t++ = '>';
					x = IKS_TAG_CHILDREN (x);
					level++;
					continue;
				} else {
					*t++ = '/';
					*t++ = '>';
				}
			} else {
				t = escape (t, IKS_CDATA_CDATA (x), IKS_CDATA_LEN (x));
			}
		}
		y = x->next;
		if (y) {
			if (0 == level) {
				if (IKS_TAG_CHILDREN (x)) {
					*t++ = '<';
					*t++ = '/';
					t = my_strcat (t, IKS_TAG_NAME (x), 0);
					*t++ = '>';
				}
				break;
			}
			x = y;
			dir = 0;
		} else {
			x = x->parent;
			level--;
			if (level >= 0) {
					*t++ = '<';
					*t++ = '/';
					t = my_strcat (t, IKS_TAG_NAME (x), 0);
					*t++ = '>';
				}
			if (level < 1) break;
			dir = 1;
		}
	}
	*t = '\0';

	return ret;
}