Example #1
0
ssize_t
tnt_auth(struct tnt_stream *s, const char *user, int ulen,
	 const char *pass, int plen)
{
	struct tnt_iheader hdr;
	struct iovec v[6]; int v_sz = 5;
	char *data = NULL, *body_start = NULL;
	int guest = !user || (ulen == 5 && !strncmp(user, "guest", 5));
	if (guest) {
		user = "******";
		ulen = 5;
	}
	encode_header(&hdr, TNT_OP_AUTH, s->reqid++);
	v[1].iov_base = (void *)hdr.header;
	v[1].iov_len  = hdr.end - hdr.header;
	char body[64]; data = body; body_start = data;

	data = mp_encode_map(data, 2);
	data = mp_encode_uint(data, TNT_USERNAME);
	data = mp_encode_strl(data, ulen);
	v[2].iov_base = body_start;
	v[2].iov_len  = data - body_start;
	v[3].iov_base = (void *)user;
	v[3].iov_len  = ulen;
	body_start = data;
	data = mp_encode_uint(data, TNT_TUPLE);
	if (!guest) {
		data = mp_encode_array(data, 2);
		data = mp_encode_str(data, "chap-sha1", strlen("chap-sha1"));
		data = mp_encode_strl(data, TNT_SCRAMBLE_SIZE);
		char salt[64], scramble[TNT_SCRAMBLE_SIZE];
		base64_decode(TNT_SNET_CAST(s)->greeting + TNT_VERSION_SIZE,
			      TNT_SALT_SIZE, salt, 64);
		tnt_scramble_prepare(scramble, salt, pass, plen);
		v[5].iov_base = scramble;
		v[5].iov_len  = TNT_SCRAMBLE_SIZE;
		v_sz++;
	} else {
		data = mp_encode_array(data, 0);
	}
	v[4].iov_base = body_start;
	v[4].iov_len  = data - body_start;

	size_t package_len = 0;
	for (int i = 1; i < v_sz; ++i) {
		package_len += v[i].iov_len;
	}
	char len_prefix[9];
	char *len_end = mp_encode_luint32(len_prefix, package_len);
	v[0].iov_base = len_prefix;
	v[0].iov_len = len_end - len_prefix;
	return s->writev(s, v, v_sz);
}
Example #2
0
static void
test_next_on_map(uint32_t count)
{
	note("next/check on map(%u)", count);
	char *d1 = data;
	d1 = mp_encode_map(d1, count);
	for (uint32_t i = 0; i < 2 * count; i++) {
		d1 = mp_encode_uint(d1, i % 0x7f); /* one byte */
	}
	uint32_t len = 2 * count + mp_sizeof_map(count);
	const char *d2 = data;
	const char *d3 = data;
	ok(!mp_check(&d2, data + BUF_MAXLEN), "mp_check(map %u))", count);
	is((d1 - data), (ptrdiff_t)len, "len(map %u) == %u", count, len);
	is((d2 - data), (ptrdiff_t)len, "len(mp_check(map %u)) == %u", count, len);
	mp_next(&d3);
	is((d3 - data), (ptrdiff_t)len, "len(mp_next(map %u)) == %u", count, len);
}
Example #3
0
ssize_t
tnt_update(struct tnt_stream *s, uint32_t space, uint32_t index,
	   struct tnt_stream *key, struct tnt_stream *ops)
{
	if (tnt_object_verify(key, MP_ARRAY))
		return -1;
	if (tnt_object_verify(ops, MP_ARRAY))
		return -1;
	struct tnt_iheader hdr;
	struct iovec v[6]; int v_sz = 6;
	char *data = NULL, *body_start = NULL;
	encode_header(&hdr, TNT_OP_UPDATE, s->reqid++);
	v[1].iov_base = (void *)hdr.header;
	v[1].iov_len  = hdr.end - hdr.header;
	char body[64]; body_start = body; data = body;

	data = mp_encode_map(data, 4);
	data = mp_encode_uint(data, TNT_SPACE);
	data = mp_encode_uint(data, space);
	data = mp_encode_uint(data, TNT_INDEX);
	data = mp_encode_uint(data, index);
	data = mp_encode_uint(data, TNT_KEY);
	v[2].iov_base = (void *)body_start;
	v[2].iov_len  = data - body_start;
	body_start = data;
	v[3].iov_base = TNT_SBUF_DATA(key);
	v[3].iov_len  = TNT_SBUF_SIZE(key);
	data = mp_encode_uint(data, TNT_TUPLE);
	v[4].iov_base = (void *)body_start;
	v[4].iov_len  = data - body_start;
	body_start = data;
	v[5].iov_base = TNT_SBUF_DATA(ops);
	v[5].iov_len  = TNT_SBUF_SIZE(ops);

	size_t package_len = 0;
	for (int i = 1; i < v_sz; ++i)
		package_len += v[i].iov_len;
	char len_prefix[9];
	char *len_end = mp_encode_luint32(len_prefix, package_len);
	v[0].iov_base = len_prefix;
	v[0].iov_len = len_end - len_prefix;
	return s->writev(s, v, v_sz);
}
Example #4
0
static ssize_t
tnt_rpc_base(struct tnt_stream *s, const char *proc, size_t proc_len,
	     struct tnt_stream *args, enum tnt_request_t op)
{
	if (!proc || proc_len == 0)
		return -1;
	if (tnt_object_verify(args, MP_ARRAY))
		return -1;
	uint32_t fld = (is_call(op) ? TNT_FUNCTION : TNT_EXPRESSION);
	struct tnt_iheader hdr;
	struct iovec v[6]; int v_sz = 6;
	char *data = NULL, *body_start = NULL;
	encode_header(&hdr, op, s->reqid++);
	v[1].iov_base = (void *)hdr.header;
	v[1].iov_len  = hdr.end - hdr.header;
	char body[64]; body_start = body; data = body;

	data = mp_encode_map(data, 2);
	data = mp_encode_uint(data, fld);
	data = mp_encode_strl(data, proc_len);
	v[2].iov_base = body_start;
	v[2].iov_len  = data - body_start;
	v[3].iov_base = (void *)proc;
	v[3].iov_len  = proc_len;
	body_start = data;
	data = mp_encode_uint(data, TNT_TUPLE);
	v[4].iov_base = body_start;
	v[4].iov_len  = data - body_start;
	v[5].iov_base = TNT_SBUF_DATA(args);
	v[5].iov_len  = TNT_SBUF_SIZE(args);

	size_t package_len = 0;
	for (int i = 1; i < v_sz; ++i)
		package_len += v[i].iov_len;
	char len_prefix[9];
	char *len_end = mp_encode_luint32(len_prefix, package_len);
	v[0].iov_base = len_prefix;
	v[0].iov_len = len_end - len_prefix;
	return s->writev(s, v, v_sz);
}
Example #5
0
static int
test_overflow()
{
	plan(4);
	header();

	const char *chk;
	char *d;
	d = data;
	chk = data;
	d = mp_encode_array(d, 1);
	d = mp_encode_array(d, UINT32_MAX);
	is(mp_check(&chk, d), 1, "mp_check array overflow")

	d = data;
	chk = data;
	d = mp_encode_array(d, 1);
	d = mp_encode_map(d, UINT32_MAX);
	is(mp_check(&chk, d), 1, "mp_check map overflow")

	d = data;
	chk = data;
	d = mp_encode_array(d, 2);
	d = mp_encode_str(d, "", 0);
	d = mp_encode_strl(d, UINT32_MAX);
	is(mp_check(&chk, d), 1, "mp_check str overflow")

	d = data;
	chk = data;
	d = mp_encode_array(d, 2);
	d = mp_encode_bin(d, "", 0);
	d = mp_encode_binl(d, UINT32_MAX);
	is(mp_check(&chk, d), 1, "mp_check bin overflow")

	footer();
	return check_plan();
}
Example #6
0
int
test_mp_print()
{
	plan(10);
	header();

	char msgpack[128];
	char *d = msgpack;
	d = mp_encode_array(d, 6);
	d = mp_encode_int(d, -5);
	d = mp_encode_uint(d, 42);
	d = mp_encode_str(d, "kill bill", 9);
	d = mp_encode_map(d, 6);
	d = mp_encode_str(d, "bool true", 9);
	d = mp_encode_bool(d, true);
	d = mp_encode_str(d, "bool false", 10);
	d = mp_encode_bool(d, false);
	d = mp_encode_str(d, "null", 4);
	d = mp_encode_nil(d);
	d = mp_encode_str(d, "float", 5);
	d = mp_encode_float(d, 3.14);
	d = mp_encode_str(d, "double", 6);
	d = mp_encode_double(d, 3.14);
	d = mp_encode_uint(d, 100);
	d = mp_encode_uint(d, 500);
	*d++ = 0xd4; /* let's pack smallest fixed ext */
	*d++ = 0;
	*d++ = 0;
	char bin[] = "\x12test\x34\b\t\n\"bla\\-bla\"\f\r";
	d = mp_encode_bin(d, bin, sizeof(bin));
	assert(d <= msgpack + sizeof(msgpack));

	const char *expected =
		"[-5, 42, \"kill bill\", "
		"{\"bool true\": true, \"bool false\": false, \"null\": null, "
		"\"float\": 3.14, \"double\": 3.14, 100: 500}, undefined, "
		"\"\\u0012test4\\b\\t\\n\\\"bla\\\\-bla\\\"\\f\\r\\u0000\"]";
	int esize = strlen(expected);

	char result[256];

	int fsize = mp_snprint(result, sizeof(result), msgpack);
	ok(fsize == esize, "mp_snprint return value");
	ok(strcmp(result, expected) == 0, "mp_snprint result");

	fsize = mp_snprint(NULL, 0, msgpack);
	ok(fsize == esize, "mp_snprint limit = 0");

	fsize = mp_snprint(result, 1, msgpack);
	ok(fsize == esize && result[0] == '\0', "mp_snprint limit = 1");

	fsize = mp_snprint(result, 2, msgpack);
	ok(fsize == esize && result[1] == '\0', "mp_snprint limit = 2");

	fsize = mp_snprint(result, esize, msgpack);
	ok(fsize == esize && result[esize - 1] == '\0',
	   "mp_snprint limit = expected");

	fsize = mp_snprint(result, esize + 1, msgpack);
	ok(fsize == esize && result[esize] == '\0',
	   "mp_snprint limit = expected + 1");

	FILE *tmpf = tmpfile();
	if (tmpf != NULL) {
		int fsize = mp_fprint(tmpf, msgpack);
		ok(fsize == esize, "mp_fprint return value");
		(void) rewind(tmpf);
		int rsize = fread(result, 1, sizeof(result), tmpf);
		ok(rsize == esize && memcmp(result, expected, esize) == 0,
		   "mp_fprint result");
		fclose(tmpf);
	}

	/* stdin is read-only */
	int rc = mp_fprint(stdin, msgpack);
	is(rc, -1, "mp_fprint I/O error");

	footer();
	return check_plan();
}
Example #7
0
void _mpack_item(SV *res, SV *o)
{
	size_t len, res_len, new_len;
	char *s, *res_s;
	res_s = SvPVbyte(res, res_len);
	unsigned i;

	if (!SvOK(o)) {
		new_len = res_len + mp_sizeof_nil();
		res_s = SvGROW(res, new_len);
		SvCUR_set(res, new_len);
		mp_encode_nil(res_s + res_len);
		return;
	}

	if (SvROK(o)) {
		o = SvRV(o);
		if (SvOBJECT(o)) {
			SvGETMAGIC(o);
			HV *stash = SvSTASH(o);
			GV *mtd = gv_fetchmethod_autoload(stash, "msgpack", 0);
			if (!mtd)
				croak("Object has no method 'msgpack'");
			dSP;
			ENTER;
			SAVETMPS;
			PUSHMARK(SP);
			XPUSHs (sv_bless (sv_2mortal (newRV_inc(o)), stash));
			PUTBACK;
			call_sv((SV *)GvCV(mtd), G_SCALAR);
			SPAGAIN;

			SV *pkt = POPs;

			if (!SvOK(pkt))
				croak("O->msgpack returned undef");

			s = SvPV(pkt, len);

			new_len = res_len + len;
			res_s = SvGROW(res, new_len);
			SvCUR_set(res, new_len);
			memcpy(res_s + res_len, s, len);

			PUTBACK;
			FREETMPS;
			LEAVE;

			return;
		}

		switch(SvTYPE(o)) {
			case SVt_PVAV: {
				AV *a = (AV *)o;
				len = av_len(a) + 1;
				new_len = res_len + mp_sizeof_array(len);
				res_s = SvGROW(res, new_len);
				SvCUR_set(res, new_len);
				mp_encode_array(res_s + res_len, len);

				for (i = 0; i < len; i++) {
					SV **item = av_fetch(a, i, 0);
					if (!item)
						_mpack_item(res, 0);
					else
						_mpack_item(res, *item);
				}

				break;
			}
			case SVt_PVHV: {
				HV *h = (HV *)o;
				len = hv_iterinit(h);
				new_len = res_len + mp_sizeof_map(len);
				res_s = SvGROW(res, new_len);
				SvCUR_set(res, new_len);
				mp_encode_map(res_s + res_len, len);

				for (;;) {
					HE * iter = hv_iternext(h);
					if (!iter)
						break;

					SV *k = hv_iterkeysv(iter);
					SV *v = HeVAL(iter);
					_mpack_item(res, k);
					_mpack_item(res, v);

				}

				break;
			}

			default:
				croak("Can't serialize reference");
		}
		return;
	}

	switch(SvTYPE(o)) {
		case SVt_PV:
		case SVt_PVIV:
		case SVt_PVNV:
		case SVt_PVMG:
		case SVt_REGEXP:
			if (!looks_like_number(o)) {
				s = SvPV(o, len);
				new_len = res_len + mp_sizeof_str(len);
				res_s = SvGROW(res, new_len);
				SvCUR_set(res, new_len);
				mp_encode_str(res_s + res_len, s, len);
				break;
			}

		case SVt_NV: {
			NV v = SvNV(o);
			IV iv = (IV)v;

			if (v != iv) {
				new_len = res_len + mp_sizeof_double(v);
				res_s = SvGROW(res, new_len);
				SvCUR_set(res, new_len);
				mp_encode_double(res_s + res_len, v);
				break;
			}
		}
		case SVt_IV: {
			IV v = SvIV(o);
			if (v >= 0) {
				new_len = res_len + mp_sizeof_uint(v);
				res_s = SvGROW(res, new_len);
				SvCUR_set(res, new_len);
				mp_encode_uint(res_s + res_len, v);
			} else {
				new_len = res_len + mp_sizeof_int(v);
				res_s = SvGROW(res, new_len);
				SvCUR_set(res, new_len);
				mp_encode_int(res_s + res_len, v);
			}
			break;
		}
		default:
			croak("Internal msgpack error %d", SvTYPE(o));
	}
}