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); }
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); }
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(); }