Ejemplo n.º 1
0
static
void test_load_v2_key(void)
{
	const char *keys[] = {
		"-----BEGIN PRIVATE KEY-----\n" \
"MGcCAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcETTBLAgEBBCC25AkD65uhlZXCAdwN\n" \
"yLJV2ui8A/CUyqyEMrezvwgMO6EkAyIAAybRUR3MsH0+0PQcDwkrXOJ9aePwzTQV\n" \
"DN51+n1JCxbI\n" \
"-----END PRIVATE KEY-----\n",
		"2\t1.2.840.10045.3.1.7\t0\t0000002100b6e40903eb9ba19595c201dc0dc8b255dae8bc03f094caac8432b7b3bf080c3b\tab13d251976dedab546b67354e7678821740dd534b749c2857f66bf62bbaddfd",
		"2\t1.2.840.10045.3.1.7\t2\taes-256-ctr\t2b19763d4bbf7754\tsha256\t2048\tc36fa194669a1aec400eae32fbadaa7c58b14f53c464cfbb0a4b61fbe24ab7750637c4025d\tab13d251976dedab546b67354e7678821740dd534b749c2857f66bf62bbaddfd",
		"2\t1.2.840.10045.3.1.7\t1\taes-256-ctr\t7c7f1d12a7c011de\tsha256\t2048\tf5d1de11d58a81b141cf038012a618623e9d7b18062deeb3a4e35872c62ca0837db8688370\t021abfbc5bc4f6cf49c40b9fc388c4616ea079941675f477ee4557df1919626d35\tab13d251976dedab546b67354e7678821740dd534b749c2857f66bf62bbaddfd\tab13d251976dedab546b67354e7678821740dd534b749c2857f66bf62bbaddfd"
	};

	test_begin("test_load_v2_key");
	const char *error = NULL;
	buffer_t *tmp = buffer_create_dynamic(default_pool, 256);

	struct dcrypt_private_key *priv,*priv2;

	test_assert_idx(dcrypt_key_load_private(&priv2, DCRYPT_FORMAT_PEM, keys[0], NULL, NULL, &error), 0);
	test_assert_idx(dcrypt_key_store_private(priv2, DCRYPT_FORMAT_PEM, NULL, tmp, NULL, NULL, &error), 0);
	test_assert_idx(strcmp(str_c(tmp), keys[0])==0, 0);
	buffer_set_used_size(tmp, 0);

	test_assert_idx(dcrypt_key_load_private(&priv, DCRYPT_FORMAT_DOVECOT, keys[1], NULL, NULL, &error), 1);
	test_assert_idx(dcrypt_key_store_private(priv, DCRYPT_FORMAT_DOVECOT, NULL, tmp, NULL, NULL, &error), 1);
	test_assert_idx(strcmp(str_c(tmp), keys[1])==0, 1);
	buffer_set_used_size(tmp, 0);
	dcrypt_key_free_private(&priv);

	test_assert_idx(dcrypt_key_load_private(&priv, DCRYPT_FORMAT_DOVECOT, keys[2], "This Is Sparta", NULL, &error), 2);
	test_assert_idx(dcrypt_key_store_private(priv, DCRYPT_FORMAT_DOVECOT, "aes-256-ctr", tmp, "This Is Sparta", NULL, &error), 2);
	buffer_set_used_size(tmp, 0);
	dcrypt_key_free_private(&priv);

	struct dcrypt_public_key *pub = NULL;
	dcrypt_key_convert_private_to_public(priv2, &pub);
	test_assert_idx(dcrypt_key_load_private(&priv, DCRYPT_FORMAT_DOVECOT, keys[3], NULL, priv2, &error), 3);
	test_assert_idx(dcrypt_key_store_private(priv, DCRYPT_FORMAT_DOVECOT, "ecdh-aes-256-ctr", tmp, NULL, pub, &error), 3);
	buffer_set_used_size(tmp, 0);
	dcrypt_key_free_private(&priv2);
	dcrypt_key_free_private(&priv);
	dcrypt_key_free_public(&pub);

	buffer_free(&tmp);

	if (error != NULL) error = NULL;

	test_end();
}
Ejemplo n.º 2
0
static void test_quoted_printable_decode(void)
{
	static struct test_quoted_printable_decode_data data[] = {
		{ "foo  \r\nbar=", "foo\r\nbar", 1, 0 },
		{ "foo\t=\nbar", "foo\tbar", 0, 0 },
		{ "foo = \n=01", "foo \001", 0, 0 },
		{ "foo =\t\r\nbar", "foo bar", 0, 0 },
		{ "foo =\r\n=01", "foo \001", 0, 0 },
		{ "foo  \nbar=", "foo\nbar", 1, 0 },
		{ "=0A=0D  ", "\n\r", 2, 0 },
		{ "foo_bar", "foo_bar", 0, 0 },
		{ "foo=", "foo", 1, 0 },
		{ "foo=  ", "foo", 3, 0 },
		{ "foo=A", "foo", 2, 0 },
		{ "foo=Ax", "foo=Ax", 0, -1 },
		{ "foo=Ax=xy", "foo=Ax=xy", 0, -1 }
	};
	buffer_t *buf;
	unsigned int i, start, end, len;
	size_t src_pos;
	int ret;

	test_begin("quoted printable decode");
	buf = buffer_create_dynamic(pool_datastack_create(), 128);
	for (i = 0; i < N_ELEMENTS(data); i++) {
		len = strlen(data[i].input);
		ret = quoted_printable_decode((const void *)data[i].input, len,
					      &src_pos, buf);
		test_assert(ret == data[i].ret);
		test_assert(src_pos + data[i].end_skip == len);
		test_assert(strcmp(data[i].output, str_c(buf)) == 0);

		buffer_set_used_size(buf, 0);
		for (start = 0, end = 1; end <= len; ) {
			quoted_printable_decode(CONST_PTR_OFFSET(data[i].input, start),
						end - start, &src_pos, buf);
			src_pos += start;
			start = src_pos;
			if (src_pos <= end)
				end++;
			else
				end = src_pos + 1;
		}
		test_assert(src_pos + data[i].end_skip == len);
		test_assert(strcmp(data[i].output, str_c(buf)) == 0);
		buffer_set_used_size(buf, 0);
	}
	test_end();
}
Ejemplo n.º 3
0
static void remove_subj_trailers(buffer_t *buf, size_t start_pos,
				 bool *is_reply_or_forward_r)
{
	const char *data;
	size_t orig_size, size;

	/* subj-trailer    = "(fwd)" / WSP */
	data = buffer_get_data(buf, &orig_size);

	if (orig_size < 1) /* size includes trailing \0 */
		return;

	for (size = orig_size-1; size > start_pos; ) {
		if (data[size-1] == ' ')
			size--;
		else if (size >= 5 &&
			 memcmp(data + size - 5, "(FWD)", 5) == 0) {
			*is_reply_or_forward_r = TRUE;
			size -= 5;
		} else {
			break;
		}
	}

	if (size != orig_size-1) {
		buffer_set_used_size(buf, size);
		buffer_append_c(buf, '\0');
	}
}
Ejemplo n.º 4
0
void fts_icu_lcase(string_t *dest_utf8, const char *src_utf8)
{
    struct UCaseMap *csm = fts_icu_csm();
    size_t avail_bytes, dest_pos = dest_utf8->used;
    char *dest_data;
    int dest_full_len;
    UErrorCode err = U_ZERO_ERROR;

    avail_bytes = buffer_get_writable_size(dest_utf8) - dest_pos;
    dest_data = buffer_get_space_unsafe(dest_utf8, dest_pos, avail_bytes);

    dest_full_len = ucasemap_utf8ToLower(csm, dest_data, avail_bytes,
                                         src_utf8, -1, &err);
    if (err == U_BUFFER_OVERFLOW_ERROR) {
        err = U_ZERO_ERROR;
        dest_data = buffer_get_space_unsafe(dest_utf8, dest_pos, dest_full_len);
        dest_full_len = ucasemap_utf8ToLower(csm, dest_data, dest_full_len,
                                             src_utf8, -1, &err);
        i_assert(err != U_BUFFER_OVERFLOW_ERROR);
    }
    if (U_FAILURE(err)) {
        i_fatal("LibICU ucasemap_utf8ToLower() failed: %s",
                u_errorName(err));
    }
    buffer_set_used_size(dest_utf8, dest_full_len);
}
Ejemplo n.º 5
0
void message_decoder_decode_reset(struct message_decoder_context *ctx)
{
	i_free_and_null(ctx->content_charset);
	ctx->message_cte = MESSAGE_CTE_78BIT;
	ctx->charset_utf8 = TRUE;
	buffer_set_used_size(ctx->encoding_buf, 0);
}
static bool
fts_tokenizer_generic_simple_current_token(struct generic_fts_tokenizer *tok,
                                           const char **token_r)
{
	const unsigned char *data = tok->token->data;
	size_t len = tok->token->used;

	if (tok->untruncated_length <= tok->max_length) {
		/* Remove the trailing apostrophe - it was made
		   into U+0027 earlier. There can be only a single such
		   apostrophe, because otherwise the token would have already
		   been split. We also want to remove the trailing apostrophe
		   only if it's the the last character in the nontruncated
		   token - a truncated token may end with apostrophe. */
		if (len > 0 && data[len-1] == '\'') {
			len--;
			i_assert(len > 0 && data[len-1] != '\'');
		}
	} else {
		fts_tokenizer_delete_trailing_partial_char(data, &len);
	}
	i_assert(len <= tok->max_length);

	*token_r = len == 0 ? "" :
		t_strndup(tok->token->data, len);
	buffer_set_used_size(tok->token, 0);
	tok->untruncated_length = 0;
	tok->prev_letter = LETTER_TYPE_NONE;
	return len > 0;
}
Ejemplo n.º 7
0
static void test_quoted_printable_decode_final(void)
{
	static struct test_quoted_printable_decode_data data[] = {
		{ "=0A=0D  ", "\n\r", 2, 0 },
		{ "foo=", "foo", 1, 0 },
		{ "foo  ", "foo", 2, 0 },
		{ "foo=  ", "foo", 3, 0 },
		{ "foo=A", "foo", 2, -1 }
	};
	buffer_t *buf;
	unsigned int i, len;
	size_t src_pos;
	int ret;

	test_begin("quoted printable decode final");
	buf = buffer_create_dynamic(pool_datastack_create(), 128);
	for (i = 0; i < N_ELEMENTS(data); i++) {
		len = strlen(data[i].input);
		ret = quoted_printable_decode_final((const void *)data[i].input,
						    len, &src_pos, buf);
		test_assert(ret == data[i].ret);
		test_assert(src_pos + data[i].end_skip == len);
		test_assert(strcmp(data[i].output, str_c(buf)) == 0);

		buffer_set_used_size(buf, 0);
	}
	test_end();
}
Ejemplo n.º 8
0
static void test_buffer_set_used_size(void)
{
	buffer_t *buf;

	test_begin("buffer_set_used_size");
	buf = t_buffer_create(8);
	memset(buffer_append_space_unsafe(buf, 7), 'a', 7);
	buffer_set_used_size(buf, 4);
	test_assert(memcmp(buffer_get_space_unsafe(buf, 0, 7), "aaaa\0\0\0", 7) == 0);
	memset(buffer_get_space_unsafe(buf, 4, 7), 'b', 7);
	buffer_set_used_size(buf, 10);
	test_assert(memcmp(buffer_append_space_unsafe(buf, 1), "\0", 1) == 0);
	buffer_set_used_size(buf, 11);
	test_assert(memcmp(buffer_get_space_unsafe(buf, 0, 11), "aaaabbbbbb\0", 11) == 0);
	test_end();
}
Ejemplo n.º 9
0
void fts_icu_utf16_to_utf8(string_t *dest_utf8, const UChar *src_utf16,
                           unsigned int src_len)
{
    int32_t dest_len = 0;
    int32_t sub_num = 0;
    char *dest_data, *retp = NULL;
    UErrorCode err = U_ZERO_ERROR;

    /* try to encode with the current buffer size */
    dest_data = buffer_get_space_unsafe(dest_utf8, 0,
                                        buffer_get_writable_size(dest_utf8));
    retp = u_strToUTF8WithSub(dest_data, buffer_get_writable_size(dest_utf8),
                              &dest_len, src_utf16, src_len,
                              UNICODE_REPLACEMENT_CHAR, &sub_num, &err);
    if (err == U_BUFFER_OVERFLOW_ERROR) {
        /* try again with a larger buffer */
        dest_data = buffer_get_space_unsafe(dest_utf8, 0, dest_len);
        err = U_ZERO_ERROR;
        retp = u_strToUTF8WithSub(dest_data, buffer_get_writable_size(dest_utf8), &dest_len,
                                  src_utf16, src_len,
                                  UNICODE_REPLACEMENT_CHAR,
                                  &sub_num, &err);
    }
    if (U_FAILURE(err)) {
        i_panic("LibICU u_strToUTF8WithSub() failed: %s",
                u_errorName(err));
    }
    buffer_set_used_size(dest_utf8, dest_len);
    i_assert(retp == dest_data);
}
Ejemplo n.º 10
0
static void test_fts_icu_translate_resize(void)
{
	const char *translit_id = "Any-Hex";
	const char *src_utf8 = "FOO";
	buffer_t *dest, *src_utf16;
	UTransliterator *translit;
	const char *error;
	unsigned int i;

	test_begin("fts_icu_translate_resize resize");

	src_utf16 = buffer_create_dynamic(pool_datastack_create(), 16);
	translit = get_translit(translit_id);
	for (i = 2; i <= 20; i++) {
		buffer_set_used_size(src_utf16, 0);
		fts_icu_utf8_to_utf16(src_utf16, src_utf8);
		dest = buffer_create_dynamic(pool_datastack_create(), i);
		test_assert(buffer_get_size(dest) == i);
		test_assert(fts_icu_translate(dest, src_utf16->data,
					      src_utf16->used/sizeof(UChar),
					      translit, &error) == 0);
	}

	utrans_close(translit);
	test_end();
}
Ejemplo n.º 11
0
static void
mail_transaction_log_file_add_to_list(struct mail_transaction_log_file *file)
{
	struct mail_transaction_log_file **p;

	file->sync_offset = file->hdr.hdr_size;
	file->sync_highest_modseq = file->hdr.initial_modseq;
	mail_transaction_log_file_skip_to_head(file);

	/* insert it to correct position */
	for (p = &file->log->files; *p != NULL; p = &(*p)->next) {
		if ((*p)->hdr.file_seq > file->hdr.file_seq)
			break;
		i_assert((*p)->hdr.file_seq < file->hdr.file_seq);
	}

	file->next = *p;
	*p = file;

	if (file->buffer != NULL) {
		/* if we read any unfinished data, make sure the buffer gets
		   truncated. */
		(void)mail_transaction_log_file_sync(file);
		buffer_set_used_size(file->buffer,
				     file->sync_offset - file->buffer_offset);
	}
}
Ejemplo n.º 12
0
static bool remove_subj_fwd_hdr(buffer_t *buf, size_t *start_pos,
				bool *is_reply_or_forward_r)
{
	const char *data;
	size_t size;

	/* subj-fwd        = subj-fwd-hdr subject subj-fwd-trl
	   subj-fwd-hdr    = "[fwd:"
	   subj-fwd-trl    = "]" */
	data = buffer_get_data(buf, &size);

	if (strncmp(data + *start_pos, "[FWD:", 5) != 0)
		return FALSE;

	if (data[size-2] != ']')
		return FALSE;

	*is_reply_or_forward_r = TRUE;

	buffer_set_used_size(buf, size-2);
	buffer_append_c(buf, '\0');

	*start_pos += 5;
	return TRUE;
}
Ejemplo n.º 13
0
static int
mail_transaction_log_file_read_more(struct mail_transaction_log_file *file)
{
	void *data;
	size_t size;
	uint32_t read_offset;
	ssize_t ret;

	read_offset = file->buffer_offset + file->buffer->used;

	do {
		data = buffer_append_space_unsafe(file->buffer, LOG_PREFETCH);
		ret = pread(file->fd, data, LOG_PREFETCH, read_offset);
		if (ret > 0)
			read_offset += ret;

		size = read_offset - file->buffer_offset;
		buffer_set_used_size(file->buffer, size);
	} while (ret > 0 || (ret < 0 && errno == EINTR));

	file->last_size = read_offset;

	if (ret < 0) {
		if (errno == ESTALE) {
			/* log file was deleted in NFS server, fail silently */
			return 0;
		}
		log_file_set_syscall_error(file, "pread()");
		return -1;
	}
	return 1;
}
Ejemplo n.º 14
0
static int
mail_transaction_log_file_insert_read(struct mail_transaction_log_file *file,
				      uoff_t offset)
{
	void *data;
	size_t size;
	ssize_t ret;

	size = file->buffer_offset - offset;
	buffer_copy(file->buffer, size, file->buffer, 0, (size_t)-1);

	data = buffer_get_space_unsafe(file->buffer, 0, size);
	ret = pread_full(file->fd, data, size, offset);
	if (ret > 0) {
		/* success */
		file->buffer_offset -= size;
		return 1;
	}

	/* failure. don't leave ourself to inconsistent state */
	buffer_copy(file->buffer, 0, file->buffer, size, (size_t)-1);
	buffer_set_used_size(file->buffer, file->buffer->used - size);

	if (ret == 0) {
		mail_transaction_log_file_set_corrupted(file, "file shrank");
		return 0;
	} else if (errno == ESTALE) {
		/* log file was deleted in NFS server, fail silently */
		return 0;
	} else {
		log_file_set_syscall_error(file, "pread()");
		return -1;
	}
}
Ejemplo n.º 15
0
void fts_icu_utf8_to_utf16(buffer_t *dest_utf16, const char *src_utf8)
{
    UErrorCode err = U_ZERO_ERROR;
    unsigned int src_bytes = strlen(src_utf8);
    int32_t utf16_len;
    UChar *dest_data, *retp = NULL;
    int32_t avail_uchars = 0;

    /* try to encode with the current buffer size */
    avail_uchars = buffer_get_writable_size(dest_utf16) / sizeof(UChar);
    dest_data = buffer_get_space_unsafe(dest_utf16, 0,
                                        buffer_get_writable_size(dest_utf16));
    retp = u_strFromUTF8Lenient(dest_data, avail_uchars,
                                &utf16_len, src_utf8, src_bytes, &err);
    if (err == U_BUFFER_OVERFLOW_ERROR) {
        /* try again with a larger buffer */
        dest_data = buffer_get_space_unsafe(dest_utf16, 0,
                                            utf16_len * sizeof(UChar));
        err = U_ZERO_ERROR;
        retp = u_strFromUTF8Lenient(dest_data, utf16_len,
                                    &utf16_len, src_utf8,
                                    src_bytes, &err);
    }
    if (U_FAILURE(err)) {
        i_panic("LibICU u_strFromUTF8Lenient() failed: %s",
                u_errorName(err));
    }
    buffer_set_used_size(dest_utf16, utf16_len * sizeof(UChar));
    i_assert(retp == dest_data);
}
static bool verify_b(const char *str, unsigned int i, bool starts_with_a)
{
	unsigned int line_start = i, start, j, char_count = 0;
	char bufdata[1000];
	buffer_t buf;

	buffer_create_from_data(&buf, bufdata, sizeof(bufdata));
	if (strncmp(str+i, "\n\t", 2) == 0) {
		i += 2;
		line_start = i - 1;
	}

	for (;;) {
		if (strncmp(str+i, "=?utf-8?b?", 10) != 0)
			return FALSE;
		i += 10;

		start = i;
		for (; str[i] != '?'; i++) {
			if (str[i] == '\0')
				return FALSE;
		}
		buffer_set_used_size(&buf, 0);
		if (base64_decode(str+start, i-start, NULL, &buf) < 0)
			return FALSE;
		i++;

		if (!starts_with_a)
			j = 0;
		else {
			if (bufdata[0] != 'a')
				return FALSE;
			starts_with_a = FALSE;
			j = 1;
		}
		for (; j < buf.used; j += 2) {
			if (bufdata[j] != '\xc3' || bufdata[j+1] != '\xa4')
				return FALSE;
			char_count++;
		}
		if (j != buf.used)
			return FALSE;

		if (str[i++] != '=')
			return FALSE;

		if (i - line_start > 76)
			return FALSE;

		if (str[i] == '\0')
			break;
		if (strncmp(str+i, "\n\t", 2) != 0)
			return FALSE;
		i += 2;
		line_start = i - 1;
	}
	return char_count == 40;
}
Ejemplo n.º 17
0
static
void test_load_v1_key(void)
{
	test_begin("test_load_v1_key");

	buffer_t *key_1 = buffer_create_dynamic(pool_datastack_create(), 128);

	struct dcrypt_private_key *pkey = NULL, *pkey2 = NULL;
	const char *error = NULL;

	test_assert(dcrypt_key_load_private(&pkey, DCRYPT_FORMAT_DOVECOT, "1\t716\t0\t048FD04FD3612B22D32790C592CF21CEF417EFD2EA34AE5F688FA5B51BED29E05A308B68DA78E16E90B47A11E133BD9A208A2894FD01B0BEE865CE339EA3FB17AC\td0cfaca5d335f9edc41c84bb47465184cb0e2ec3931bebfcea4dd433615e77a0", NULL, NULL, &error));
	if (pkey != NULL) {
		buffer_set_used_size(key_1, 0);
		/* check that key_id matches */
		struct dcrypt_public_key *pubkey = NULL;
		dcrypt_key_convert_private_to_public(pkey, &pubkey);
		test_assert(dcrypt_key_store_public(pubkey, DCRYPT_FORMAT_DOVECOT, key_1, NULL));
		buffer_set_used_size(key_1, 0);
		dcrypt_key_id_public(pubkey, "sha256", key_1, &error);
		test_assert(strcmp("792caad4d38c9eb2134a0cbc844eae386116de096a0ccafc98479825fc99b6a1", binary_to_hex(key_1->data, key_1->used)) == 0);

		dcrypt_key_free_public(&pubkey);
		pkey2 = NULL;

		test_assert(dcrypt_key_load_private(&pkey2, DCRYPT_FORMAT_DOVECOT, "1\t716\t1\t0567e6bf9579813ae967314423b0fceb14bda24749303923de9a9bb9370e0026f995901a57e63113eeb2baf0c940e978d00686cbb52bd5014bc318563375876255\t0300E46DA2125427BE968EB3B649910CDC4C405E5FFDE18D433A97CABFEE28CEEFAE9EE356C792004FFB80981D67E741B8CC036A34235A8D2E1F98D1658CFC963D07EB\td0cfaca5d335f9edc41c84bb47465184cb0e2ec3931bebfcea4dd433615e77a0\t7c9a1039ea2e4fed73e81dd3ffc3fa22ea4a28352939adde7bf8ea858b00fa4f", NULL, pkey, &error));
		if (pkey2 != NULL) {
			buffer_set_used_size(key_1, 0);
			/* check that key_id matches */
			struct dcrypt_public_key *pubkey = NULL;
			dcrypt_key_convert_private_to_public(pkey2, &pubkey);
			test_assert(dcrypt_key_store_public(pubkey, DCRYPT_FORMAT_DOVECOT, key_1, NULL));
			buffer_set_used_size(key_1, 0);
			test_assert(dcrypt_key_id_public_old(pubkey, key_1, &error));
			test_assert(strcmp("7c9a1039ea2e4fed73e81dd3ffc3fa22ea4a28352939adde7bf8ea858b00fa4f", binary_to_hex(key_1->data, key_1->used)) == 0);

			dcrypt_key_free_public(&pubkey);
			dcrypt_key_free_private(&pkey2);
		}
		dcrypt_key_free_private(&pkey);
	}

	test_end();
}
static void fts_tokenizer_generic_reset(struct fts_tokenizer *_tok)
{
	struct generic_fts_tokenizer *tok =
		(struct generic_fts_tokenizer *)_tok;

	tok->prev_letter = LETTER_TYPE_NONE;
	tok->prev_prev_letter = LETTER_TYPE_NONE;
	tok->untruncated_length = 0;
	buffer_set_used_size(tok->token, 0);
}
Ejemplo n.º 19
0
static int dump_record(int fd, buffer_t *buf)
{
	struct fts_expunge_log_record rec;
	off_t offset;
	void *data;
	const uint32_t *expunges, *uids;
	ssize_t ret;
	size_t data_size;
	unsigned int i, uids_count;

	offset = lseek(fd, 0, SEEK_CUR);

	ret = read(fd, &rec, sizeof(rec));
	if (ret == 0)
		return 0;

	if (ret != sizeof(rec))
		i_fatal("rec read() %d != %d", (int)ret, (int)sizeof(rec));

	if (rec.record_size < sizeof(rec) + sizeof(uint32_t) ||
	    rec.record_size > INT_MAX) {
		i_fatal("Invalid record_size=%u at offset %"PRIuUOFF_T,
			rec.record_size, offset);
	}
	data_size = rec.record_size - sizeof(rec);
	buffer_set_used_size(buf, 0);
	data = buffer_append_space_unsafe(buf, data_size);
	ret = read(fd, data, data_size);
	if (ret != (ssize_t)data_size)
		i_fatal("rec read() %d != %d", (int)ret, (int)data_size);

	printf("#%"PRIuUOFF_T":\n", offset);
	printf("  checksum  = %8x\n", rec.checksum);
	printf("  size .... = %u\n", rec.record_size);
	printf("  mailbox . = %s\n", guid_128_to_string(rec.guid));

	expunges = CONST_PTR_OFFSET(data, data_size - sizeof(uint32_t));
	printf("  expunges  = %u\n", *expunges);

	printf("  uids .... = ");

	uids = data;
	uids_count = (rec.record_size - sizeof(rec) - sizeof(uint32_t)) /
		sizeof(uint32_t);
	for (i = 0; i < uids_count; i += 2) {
		if (i != 0)
			printf(",");
		if (uids[i] == uids[i+1])
			printf("%u", uids[i]);
		else
			printf("%u-%u", uids[i], uids[i+1]);
	}
	printf("\n");
	return 1;
}
Ejemplo n.º 20
0
void message_decoder_decode_reset(struct message_decoder_context *ctx)
{
	const char *error;

	if (ctx->qp != NULL)
		(void)qp_decoder_finish(ctx->qp, &error);
	i_free_and_null(ctx->content_type);
	i_free_and_null(ctx->content_charset);
	ctx->message_cte = MESSAGE_CTE_78BIT;
	buffer_set_used_size(ctx->encoding_buf, 0);
}
Ejemplo n.º 21
0
int fts_icu_translate(buffer_t *dest_utf16, const UChar *src_utf16,
                      unsigned int src_len, UTransliterator *transliterator,
                      const char **error_r)
{
    UErrorCode err = U_ZERO_ERROR;
    int32_t utf16_len = src_len;
    UChar *dest_data;
    int32_t avail_uchars, limit = src_len;
    size_t dest_pos = dest_utf16->used;

    /* translation is done in-place in the buffer. try first with the
       current buffer size. */
    buffer_append(dest_utf16, src_utf16, src_len*sizeof(UChar));

    avail_uchars = (buffer_get_writable_size(dest_utf16)-dest_pos) / sizeof(UChar);
    dest_data = buffer_get_space_unsafe(dest_utf16, dest_pos,
                                        buffer_get_writable_size(dest_utf16)-dest_pos);
    utrans_transUChars(transliterator, dest_data, &utf16_len,
                       avail_uchars, 0, &limit, &err);
    if (err == U_BUFFER_OVERFLOW_ERROR) {
        /* try again with a larger buffer */
        err = U_ZERO_ERROR;
        avail_uchars = utf16_len;
        limit = utf16_len = src_len;
        buffer_write(dest_utf16, dest_pos,
                     src_utf16, src_len*sizeof(UChar));
        dest_data = buffer_get_space_unsafe(dest_utf16, dest_pos,
                                            avail_uchars * sizeof(UChar));
        utrans_transUChars(transliterator, dest_data, &utf16_len,
                           avail_uchars, 0, &limit, &err);
        i_assert(err != U_BUFFER_OVERFLOW_ERROR);
    }
    if (U_FAILURE(err)) {
        *error_r = t_strdup_printf("LibICU utrans_transUChars() failed: %s",
                                   u_errorName(err));
        buffer_set_used_size(dest_utf16, dest_pos);
        return -1;
    }
    buffer_set_used_size(dest_utf16, utf16_len * sizeof(UChar));
    return 0;
}
Ejemplo n.º 22
0
static void str_add_nul(string_t *str)
{
	const unsigned char *data = str_data(str);
	size_t len = str_len(str);
	size_t alloc = buffer_get_size(str);

	if (len == alloc || data[len] != '\0') {
		buffer_write(str, len, "", 1);
		/* remove the \0 - we don't want to keep it */
		buffer_set_used_size(str, len);
	}
}
Ejemplo n.º 23
0
static void astream_add_body(struct attachment_istream *astream,
			     const struct message_block *block)
{
	struct attachment_istream_part *part = &astream->part;
	buffer_t *part_buf;
	size_t new_size;

	switch (part->state) {
	case MAIL_ATTACHMENT_STATE_NO:
		stream_add_data(astream, block->data, block->size);
		break;
	case MAIL_ATTACHMENT_STATE_MAYBE:
		/* we'll write data to in-memory buffer until we reach
		   attachment min_size */
		if (part->part_buf == NULL) {
			part->part_buf =
				buffer_create_dynamic(default_pool,
						      astream->set.min_size);
		}
		part_buf = part->part_buf;
		new_size = part_buf->used + block->size;
		if (new_size < astream->set.min_size) {
			buffer_append(part_buf, block->data, block->size);
			break;
		}
		/* attachment is large enough. we'll first copy the buffered
		   data from memory to temp file */
		if (astream_open_output(astream) < 0) {
			/* failed, fallback to just saving it inline */
			part->state = MAIL_ATTACHMENT_STATE_NO;
			stream_add_data(astream, part_buf->data, part_buf->used);
			stream_add_data(astream, block->data, block->size);
			break;
		}
		part->state = MAIL_ATTACHMENT_STATE_YES;
		astream_try_base64_decode(part, part_buf->data, part_buf->used);
		hash_format_loop(astream->set.hash_format,
				 part_buf->data, part_buf->used);
		o_stream_nsend(part->temp_output,
			       part_buf->data, part_buf->used);
		buffer_set_used_size(part_buf, 0);
		/* fall through to write the new data to temp file */
	case MAIL_ATTACHMENT_STATE_YES:
		astream_try_base64_decode(part, block->data, block->size);
		hash_format_loop(astream->set.hash_format,
				 block->data, block->size);
		o_stream_nsend(part->temp_output, block->data, block->size);
		break;
	}
}
Ejemplo n.º 24
0
static void test_foo(void)
{
	buffer_t *buf = buffer_create_dynamic(default_pool, 100);

	for (int i = 1; i <= 24; i++) {
		buffer_set_used_size(buf, 0);
		buffer_append_c(buf, 0xff);
		buffer_append_c(buf, 0xff);
		buffer_append_c(buf, 0xff);
		buffer_truncate_rshift_bits(buf, i);
		printf("%2d bits: %24s %s\n", i,
		       binary_to_hex(buf->data, buf->used),
		       binary_to_10(buf->data, buf->used));
	}
}
Ejemplo n.º 25
0
static int
mail_transaction_log_file_read(struct mail_transaction_log_file *file,
			       uoff_t start_offset, bool nfs_flush)
{
	int ret;

	i_assert(file->mmap_base == NULL);

	/* NFS: if file isn't locked, we're optimistic that we can read enough
	   data without flushing attribute cache. if after reading we notice
	   that we really should have read more, flush the cache and try again.
	   if file is locked, the attribute cache was already flushed when
	   refreshing the log. */
	if (file->log->nfs_flush && nfs_flush) {
		if (!file->locked)
			nfs_flush_attr_cache_unlocked(file->filepath);
		else
			nfs_flush_attr_cache_fd_locked(file->filepath, file->fd);
	}

	if (file->buffer != NULL && file->buffer_offset > start_offset) {
		/* we have to insert missing data to beginning of buffer */
		ret = mail_transaction_log_file_insert_read(file, start_offset);
		if (ret <= 0)
			return ret;
	}

	if (file->buffer == NULL) {
		file->buffer =
			buffer_create_dynamic(default_pool, LOG_PREFETCH);
		file->buffer_offset = start_offset;
	}

	if ((ret = mail_transaction_log_file_read_more(file)) <= 0)
		;
	else if (file->log->nfs_flush && !nfs_flush &&
		 mail_transaction_log_file_need_nfs_flush(file)) {
		/* we didn't read enough data. flush and try again. */
		return mail_transaction_log_file_read(file, start_offset, TRUE);
	} else if ((ret = mail_transaction_log_file_sync(file)) <= 0) {
		i_assert(ret != 0); /* ret=0 happens only with mmap */
	} else {
		i_assert(file->sync_offset >= file->buffer_offset);
	}
	buffer_set_used_size(file->buffer,
			     file->sync_offset - file->buffer_offset);
	return ret;
}
Ejemplo n.º 26
0
static bool message_decode_header(struct message_decoder_context *ctx,
				  struct message_header_line *hdr,
				  struct message_block *output)
{
	size_t value_len;

	if (hdr->continues) {
		hdr->use_full_value = TRUE;
		return FALSE;
	}

	T_BEGIN {
		if (hdr->name_len == 12 &&
		    strcasecmp(hdr->name, "Content-Type") == 0)
			parse_content_type(ctx, hdr);
		if (hdr->name_len == 25 &&
		    strcasecmp(hdr->name, "Content-Transfer-Encoding") == 0)
			ctx->message_cte = message_decoder_parse_cte(hdr);
	} T_END;

	buffer_set_used_size(ctx->buf, 0);
	message_header_decode_utf8(hdr->full_value, hdr->full_value_len,
				   ctx->buf, ctx->normalizer);
	value_len = ctx->buf->used;

	if (ctx->normalizer != NULL) {
		(void)ctx->normalizer(hdr->name, hdr->name_len, ctx->buf);
		buffer_append_c(ctx->buf, '\0');
	} else {
		if (!uni_utf8_get_valid_data((const unsigned char *)hdr->name,
					     hdr->name_len, ctx->buf))
			buffer_append_c(ctx->buf, '\0');
	}

	ctx->hdr = *hdr;
	ctx->hdr.full_value = ctx->buf->data;
	ctx->hdr.full_value_len = value_len;
	ctx->hdr.value_len = 0;
	if (ctx->buf->used != value_len) {
		ctx->hdr.name = CONST_PTR_OFFSET(ctx->buf->data,
						 ctx->hdr.full_value_len);
		ctx->hdr.name_len = ctx->buf->used - 1 - value_len;
	}

	output->hdr = &ctx->hdr;
	return TRUE;
}
Ejemplo n.º 27
0
Archivo: mail.c Proyecto: zatsepin/core
void mail_generate_guid_128_hash(const char *guid, guid_128_t guid_128_r)
{
	unsigned char sha1_sum[SHA1_RESULTLEN];
	buffer_t buf;

	if (guid_128_from_string(guid, guid_128_r) < 0) {
		/* not 128bit hex. use a hash of it instead. */
		buffer_create_from_data(&buf, guid_128_r, GUID_128_SIZE);
		buffer_set_used_size(&buf, 0);
		sha1_get_digest(guid, strlen(guid), sha1_sum);
#if SHA1_RESULTLEN < GUID_128_SIZE
#  error not possible
#endif
		buffer_append(&buf,
			      sha1_sum + SHA1_RESULTLEN - GUID_128_SIZE,
			      GUID_128_SIZE);
	}
}
Ejemplo n.º 28
0
static int ssl_refresh_parameters(struct master_service *service)
{
#define BUF_APPEND_SIZE 1024
	const char *path;
	buffer_t *buf;
	void *data;
	ssize_t ret;
	int fd;

	if (ioloop_time == 0 ||
	    service->ssl_params_last_refresh > ioloop_time - SSL_PARAMS_CHECK_INTERVAL)
		return 0;
	service->ssl_params_last_refresh = ioloop_time;

	path = t_strdup_printf("%s/"SSL_PARAMETERS_PATH, service->set->base_dir);
	fd = net_connect_unix(path);
	if (fd == -1) {
		i_error("connect(%s) failed: %m", path);
		return -1;
	}
	net_set_nonblock(fd, FALSE);

	buf = buffer_create_dynamic(default_pool, BUF_APPEND_SIZE*2);
	for (;;) {
		data = buffer_append_space_unsafe(buf, BUF_APPEND_SIZE);
		ret = read(fd, data, BUF_APPEND_SIZE);
		buffer_set_used_size(buf, buf->used - BUF_APPEND_SIZE +
				     (ret < 0 ? 0 : ret));
		if (ret <= 0)
			break;
	}
	if (ret < 0)
		i_error("read(%s) failed: %m", path);
	else if (ssl_iostream_context_import_params(service->ssl_ctx, buf) < 0) {
		i_error("Corrupted SSL parameters file in state_dir: "
			"ssl-parameters.dat - disabling SSL %u", (int)buf->used);
		ret = -1;
	}
	i_close_fd(&fd);
	buffer_free(&buf);
	return ret < 0 ? -1 : 0;
}
Ejemplo n.º 29
0
static ssize_t
mail_transaction_log_file_read_header(struct mail_transaction_log_file *file)
{
	void *dest;
	size_t pos, dest_size;
	ssize_t ret;

	i_assert(file->buffer == NULL && file->mmap_base == NULL);

	memset(&file->hdr, 0, sizeof(file->hdr));
	if (file->last_size < mmap_get_page_size() && file->last_size > 0) {
		/* just read the entire transaction log to memory.
		   note that if some of the data hasn't been fully committed
		   yet (hdr.size=0), the buffer must be truncated later */
		file->buffer = buffer_create_dynamic(default_pool, 4096);
		file->buffer_offset = 0;
		dest_size = file->last_size;
		dest = buffer_append_space_unsafe(file->buffer, dest_size);
	} else {
		/* read only the header */
		dest = &file->hdr;
		dest_size = sizeof(file->hdr);
	}

	/* it's not necessarily an error to read less than wanted header size,
	   since older versions of the log format used smaller headers. */
        pos = 0;
	do {
		ret = pread(file->fd, PTR_OFFSET(dest, pos),
			    dest_size - pos, pos);
		if (ret > 0)
			pos += ret;
	} while (ret > 0 && pos < dest_size);

	if (file->buffer != NULL) {
		buffer_set_used_size(file->buffer, pos);
		memcpy(&file->hdr, file->buffer->data,
		       I_MIN(pos, sizeof(file->hdr)));
	}

	return ret < 0 ? -1 : (ssize_t)pos;
}
Ejemplo n.º 30
0
static void test_fts_icu_translate(void)
{
	const char *translit_id = "Any-Lower";
	UTransliterator *translit;
	buffer_t *dest = buffer_create_dynamic(pool_datastack_create(), 64);
	const UChar src[] = { 0xbd, 'B', 'C' };
	const char *error;
	unsigned int i;

	test_begin("fts_icu_translate");
	translit = get_translit(translit_id);
	for (i = N_ELEMENTS(src); i > 0; i--) {
		buffer_set_used_size(dest, 0);
		test_assert(fts_icu_translate(dest, src, i,
					      translit, &error) == 0);
		test_assert(dest->used == i * sizeof(UChar));
	}
	utrans_close(translit);
	test_end();
}