istream-qp-decoder.c \
istream-qp-encoder.c \
mail-html2text.c \
- mail-user-hash.c \
mbox-from.c \
message-address.c \
message-binary-part.c \
istream-header-filter.h \
istream-nonuls.h \
istream-qp.h \
- mail-user-hash.h \
mbox-from.h \
mail-html2text.h \
mail-types.h \
test-istream-qp-decoder \
test-istream-qp-encoder \
test-mail-html2text \
- test-mail-user-hash \
test-mbox-from \
test-message-address \
test-message-date \
test_rfc822_parser_LDADD = $(test_libs)
test_rfc822_parser_DEPENDENCIES = $(test_deps)
-test_mail_user_hash_SOURCES = test-mail-user-hash.c
-test_mail_user_hash_LDADD = $(test_libs)
-test_mail_user_hash_DEPENDENCIES = $(test_deps)
-
test_message_part_serialize_SOURCES = test-message-part-serialize.c
test_message_part_serialize_LDADD = $(test_libs)
test_message_part_serialize_DEPENDENCIES = $(test_deps)
+++ /dev/null
-/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "md5.h"
-#include "str.h"
-#include "var-expand.h"
-#include "mail-user-hash.h"
-
-bool mail_user_hash(const char *username, const char *format,
- unsigned int *hash_r, const char **error_r)
-{
- unsigned char md5[MD5_RESULTLEN];
- unsigned int i, hash = 0;
- int ret = 1;
-
- if (strcmp(format, "%u") == 0) {
- /* fast path */
- md5_get_digest(username, strlen(username), md5);
- } else if (strcmp(format, "%Lu") == 0) {
- /* almost as fast path */
- T_BEGIN {
- md5_get_digest(t_str_lcase(username),
- strlen(username), md5);
- } T_END;
- } else T_BEGIN {
- const struct var_expand_table tab[] = {
- { 'u', username, "user" },
- { 'n', t_strcut(username, '@'), "username" },
- { 'd', i_strchr_to_next(username, '@'), "domain" },
- { '\0', NULL, NULL }
- };
- string_t *str = t_str_new(128);
-
- ret = var_expand(str, format, tab, error_r);
- i_assert(ret >= 0);
- md5_get_digest(str_data(str), str_len(str), md5);
- } T_END_PASS_STR_IF(ret == 0, error_r);
- for (i = 0; i < sizeof(hash); i++)
- hash = (hash << CHAR_BIT) | md5[i];
- if (hash == 0) {
- /* Make sure we don't return the hash as 0, since it's often
- treated in a special way that won't work well. For example
- trying to insert it into a hash table will assert-crash. */
- hash = 1;
- }
- *hash_r = hash;
- return ret > 0;
-}
+++ /dev/null
-#ifndef MAIL_USER_HASH
-#define MAIL_USER_HASH
-
-/* Get a hash for username, based on given format. The format can use
- %n, %d and %u variables. The returned hash is never 0.
- Returns TRUE if ok, FALSE if format is invalid. */
-bool mail_user_hash(const char *username, const char *format,
- unsigned int *hash_r, const char **error_r);
-
-#endif
+++ /dev/null
-/* Copyright (c) 2020 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "buffer.h"
-#include "str.h"
-#include "mail-user-hash.h"
-#include "test-common.h"
-
-#include "md5.h"
-
-static void test_mail_user_hash(void)
-{
- struct test_case {
- const char *username;
- const char *format;
- unsigned int hash;
- } test_cases[] = {
- {
- .username = "",
- .format = "",
- .hash = 3558706393,
- },
- {
- .username = "testuser",
- .format = "",
- .hash = 3558706393,
- },
- {
- .username = "",
- .format = "%u",
- .hash = 3558706393,
- },
- {
- .username = "@",
- .format = "%u",
- .hash = 1368314517,
- },
- {
- .username = "",
- .format = "%n@%d",
- .hash = 1368314517,
- },
- {
- .username = "",
- .format = "%n",
- .hash = 3558706393,
- },
- {
- .username = "",
- .format = "%d",
- .hash = 3558706393,
- },
- {
- .username = "testuser",
- .format = "%u",
- .hash = 1570531526,
- },
- {
- .username = "testuser",
- .format = "%n",
- .hash = 1570531526,
- },
- {
- .username = "testuser",
- .format = "%d",
- .hash = 3558706393,
- },
- {
- .username = "@domain",
- .format = "%u",
- .hash = 3749630072,
- },
- {
- .username = "@domain",
- .format = "%n@%d",
- .hash = 3749630072,
- },
- {
- .username = "@domain",
- .format = "%n",
- .hash = 3558706393,
- },
- {
- .username = "@domain",
- .format = "%d",
- .hash = 2908717800,
- },
- {
- .username = "testuser@domain",
- .format = "%u",
- .hash = 3813799143,
- },
- {
- .username = "testuser@domain",
- .format = "%n@%d",
- .hash = 3813799143,
- },
- {
- .username = "testuser@domain",
- .format = "%n",
- .hash = 1570531526,
- },
- {
- .username = "testuser@domain",
- .format = "%d",
- .hash = 2908717800,
- },
- {
- .username = "test@user@domain",
- .format = "%u",
- .hash = 2029259821,
- },
- {
- .username = "test@user@domain",
- .format = "%n@%d",
- .hash = 2029259821,
- },
- {
- .username = "test@user@domain",
- .format = "%n",
- .hash = 160394189,
- },
- {
- .username = "test@user@domain",
- .format = "%d",
- .hash = 1841230927,
- }
- };
-
- test_begin("mail_user_hash");
-
- for (size_t i = 0; i < N_ELEMENTS(test_cases); i++) {
- const struct test_case *tc = &test_cases[i];
- const char *error = NULL;
- unsigned int hash;
- test_assert_idx(mail_user_hash(tc->username, tc->format, &hash,
- &error), i);
- test_assert_idx(error == NULL, i);
- test_assert_idx(hash == tc->hash, i);
- }
-
- test_end();
-}
-
-static void test_mail_user_hash_errors(void)
-{
- test_begin("mail_user_hash_errors");
-
- struct test_case {
- const char *username;
- const char *format;
- unsigned int hash;
- const char *error;
- } test_cases[] = {
- {
- .username = "testuser@domain",
- .format = "%{invalid}",
- .hash = 1466562296,
- .error = "Unknown variable '%invalid'",
- },
- };
-
- for (size_t i = 0; i < N_ELEMENTS(test_cases); i++) {
- const struct test_case *tc = &test_cases[i];
- const char *error = NULL;
- unsigned int hash = 0;
- test_assert_idx(mail_user_hash(tc->username, tc->format, &hash,
- &error) == FALSE, i);
- test_assert_idx(tc->hash == hash, i);
- test_assert_strcmp_idx(tc->error, error, i);
- test_assert_idx(tc->hash == hash, i);
- }
-
- test_end();
-}
-
-int main(void)
-{
- static void (*const test_functions[])(void) = {
- test_mail_user_hash,
- test_mail_user_hash_errors,
- NULL
- };
- return test_run(test_functions);
-}