Ejemplo n.º 1
0
void
iks_stack_delete (ikstack **sp)
{
	ikschunk *c, *tmp;
	ikstack *s;

	if (!sp) {
		return;
	}

	s = *sp;

	if (!s) {
		return;
	}

	*sp = NULL;
	c = s->meta->next;
	while (c) {
		tmp = c->next;
		iks_free (c);
		c = tmp;
	}
	c = s->data->next;
	while (c) {
		tmp = c->next;
		iks_free (c);
		c = tmp;
	}
	iks_free (s);
}
Ejemplo n.º 2
0
void
iks_parser_delete (iksparser *prs)
{
	if (prs->deleteHook) prs->deleteHook (prs->user_data);
	if (prs->stack) iks_free (prs->stack);
	if (prs->atts) iks_free (prs->atts);
	if (prs->s) iks_stack_delete (prs->s); else iks_free (prs);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
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, NULL);
	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);
}
Ejemplo n.º 7
0
// xxx needs error return value
static void
send_sasl_challenge (ikss_Stream *self, 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 (self, message);
  }
  if (x) {
    iks_insert_attrib (x, "xmlns", IKS_NS_XMPP_SASL);
    ikss_Stream_send_node (self, x); // xxx check return value
    iks_delete (x);
  }
  iks_free (message);
}
Ejemplo n.º 8
0
static void
tls_terminate(struct ikstls_data *data)
{
	gnutls_bye (data->sess, GNUTLS_SHUT_WR);
	gnutls_deinit (data->sess);
	gnutls_certificate_free_credentials (data->cred);
	iks_free (data);
}
Ejemplo n.º 9
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;
}
Ejemplo 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;
}
Ejemplo n.º 11
0
/**
 * open next file for reading
 * @param handle the file handle
 */
static switch_status_t next_file(switch_file_handle_t *handle)
{
	int loops = 0;
	struct rayo_file_context *context = handle->private_info;
	struct output_component *output = context->component ? OUTPUT_COMPONENT(context->component) : NULL;

  top:

	if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) {
		switch_core_file_close(&context->fh);
	}

	if (switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) {
		/* unsupported */
		return SWITCH_STATUS_FALSE;
	}

	if (!context->cur_doc) {
		context->cur_doc = iks_find(output->document, "document");
		if (!context->cur_doc) {
			iks_delete(output->document);
			output->document = NULL;
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <document>\n");
			return SWITCH_STATUS_FALSE;
		}
	} else {
		context->cur_doc = iks_next_tag(context->cur_doc);
	}

	/* done? */
	if (!context->cur_doc) {
		if (context->could_open && ++loops < 2 && (output->repeat_times == 0 || ++context->play_count < output->repeat_times)) {
			/* repeat all document(s) */
			if (!output->repeat_interval_ms) {
				goto top;
			}
		} else {
			/* no more files to play */
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Done playing\n");
			return SWITCH_STATUS_FALSE;
		}
	}

	if (!context->cur_doc) {
		/* play silence between repeats */
		switch_safe_free(context->ssml);
		context->ssml = switch_mprintf("silence_stream://%i", output->repeat_interval_ms);
	} else {
		/* play next document */
		iks *speak = NULL;

		switch_safe_free(context->ssml);
		context->ssml = NULL;
 		speak = iks_find(context->cur_doc, "speak");
		if (speak) {
			/* <speak> is child node */
			char *ssml_str = iks_string(NULL, speak);
			if (zstr(output->renderer)) {
				/* FS must parse the SSML */
				context->ssml = switch_mprintf("ssml://%s", ssml_str);
			} else {
				/* renderer will parse the SSML */
				if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) {
					/* pass MRCP headers */
					context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str);
				} else {
					context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str);
				}
			}
			iks_free(ssml_str);
		} else if (iks_has_children(context->cur_doc)) {
			/* check if <speak> is in CDATA */
			const char *ssml_str = NULL;
			iks *ssml = iks_child(context->cur_doc);
			if (ssml && iks_type(ssml) == IKS_CDATA) {
				ssml_str = iks_cdata(ssml);
			}
			if (zstr(ssml_str)) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <document> CDATA\n");
				return SWITCH_STATUS_FALSE;
			}
			if (zstr(output->renderer)) {
				/* FS must parse the SSML */
				context->ssml = switch_mprintf("ssml://%s", ssml_str);
			} else {
				/* renderer will parse the SSML */
				if (!zstr(output->headers) && !strncmp("unimrcp", output->renderer, 7)) {
					/* pass MRCP headers */
					context->ssml = switch_mprintf("tts://%s||%s%s", output->renderer, output->headers, ssml_str);
				} else {
					context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str);
				}
			}
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing <speak>\n");
			return SWITCH_STATUS_FALSE;
		}
	}
	if (switch_core_file_open(&context->fh, context->ssml, handle->channels, handle->samplerate, handle->flags, NULL) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to open %s\n", context->ssml);
		goto top;
	} else {
		context->could_open = 1;
	}

	handle->samples = context->fh.samples;
	handle->format = context->fh.format;
	handle->sections = context->fh.sections;
	handle->seekable = context->fh.seekable;
	handle->speed = context->fh.speed;
	handle->vol = context->fh.vol;
	handle->offset_pos = context->fh.offset_pos;
	handle->interval = context->fh.interval;

	if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
		switch_set_flag(handle, SWITCH_FILE_NATIVE);
	} else {
		switch_clear_flag(handle, SWITCH_FILE_NATIVE);
	}

	return SWITCH_STATUS_SUCCESS;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
void iks_md5_delete(iksmd5 *md5)
{
	iks_free(md5);
}