diff --git a/.gitignore b/.gitignore index 4b6ab4d..9e1e596 100644 --- a/.gitignore +++ b/.gitignore @@ -18,8 +18,8 @@ Makefile.in configure aclocal.m4 autom4te.cache/ -libscrambler-config.h -libscrambler-config.h.in +trees-config.h +trees-config.h.in config.log config.status stamp-h1 diff --git a/README.md b/README.md index f7722be..0263da4 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -Tofu Scrambler - A NaCL-based Dovecot encryption plugin +TREES - A NaCL-based Dovecot encryption plugin ======================================================= This plugin adds individually encrypted mail storage to the Dovecot IMAP server. This plugin is inspired by Posteo's [scrambler](https://github.com/posteo -/scrambler-plugin) which uses OpenSSL and RSA keypairs. Tofu Scrambler works in -a similar way, but uses the Sodium crypto library (based on NaCL). +/scrambler-plugin) which uses OpenSSL and RSA keypairs. TREES works in a +similar way, but uses the Sodium crypto library (based on NaCL). How it works: @@ -45,11 +45,11 @@ Installation * Type `make` to compile the plugin. -* Find the plugin at `src/.libs/lib18_scrambler_plugin.so`. +* Find the plugin at `src/.libs/lib18_trees_plugin.so`. * Copy to `/usr/lib/dovecot/modules/` -* Enable the plugin. For example, add `mail_plugins = expire quota scrambler` +* Enable the plugin. For example, add `mail_plugins = expire quota trees` to `/etc/dovecot/conf.d/10-mail.conf` See below for how to configure the plugin. @@ -60,24 +60,24 @@ Database In order to run, the plugin needs the following configuration values (via the dovecot environment). -* `scrambler_password` The plain user password. It's used to unlock the - `scrambler_locked_secretbox` in order to get access to the private key. +* `trees_password` The plain user password. It's used to unlock the + `trees_locked_secretbox` in order to get access to the private key. -* `scrambler_enabled` Can be either the integer `1` or `0`. +* `trees_enabled` Can be either the integer `1` or `0`. -* `scrambler_public_key` The public Curve25519 key of the user (hex string). +* `trees_public_key` The public Curve25519 key of the user (hex string). -* `scrambler_locked_secretbox` contains the Curve25519 private key of a user +* `trees_locked_secretbox` contains the Curve25519 private key of a user which is locked using the argon2 digest of the user's password (hex string). -* `scrambler_sk_nonce` 24 byte random nonce for locked_secretbox (hex string). +* `trees_sk_nonce` 24 byte random nonce for `locked_secretbox` (hex string). -* `scrambler_pwhash_opslimit` argon2 CPU usage parameter (3..10 int). +* `trees_pwhash_opslimit` argon2 CPU usage parameter (3..10 int). -* `scrambler_pwhash_memlimit` argon2 memory usage parameter (must be in range +* `trees_pwhash_memlimit` argon2 memory usage parameter (must be in range 8192 bytes to 4 TB, expressed in bytes). -* `scrambler_pwhash_salt` 16 byte random argon2 salt (hex string). +* `trees_pwhash_salt` 16 byte random argon2 salt (hex string). An example database scheme for this might be: @@ -114,8 +114,8 @@ Dovecot Configuration * `default_pass_scheme = ARGON2` recommended (Note: this will use the crypt- style argon2 digest string for authentication, which is a very different - format than is used by tofu-scrambler. It is out of tofu-scrambler's scope - how to set up Argon2 authentication with Dovecot). + format than is used by TREES. It is out of TREES's scope how to set up + Argon2 authentication with Dovecot). SQL Configuration ------------------------------------- @@ -155,14 +155,14 @@ Here is a dovecot SQL query configuration that will work with the sample 8 AS userdb_uid, \ 8 AS userdb_gid, \ CONCAT('/maildir/', mailboxes.maildir) AS userdb_home, \ - REPLACE('%w', '%%', '%%%%') AS userdb_scrambler_password, \ - storage_keys.enabled AS userdb_scrambler_enabled, \ - storage_keys.public_key AS userdb_scrambler_public_key, \ - storage_keys.locked_secretbox AS userdb_scrambler_locked_secretbox, \ - storage_keys.sk_nonce AS userdb_scrambler_sk_nonce, \ - storage_keys.pwhash_opslimit AS userdb_scrambler_pwhash_opslimit, \ - storage_keys.pwhash_memlimit AS userdb_scrambler_pwhash_memlimit, \ - storage_keys.pwhash_salt AS userdb_scrambler_pwhash_salt \ + REPLACE('%w', '%%', '%%%%') AS userdb_trees_password, \ + storage_keys.enabled AS userdb_trees_enabled, \ + storage_keys.public_key AS userdb_trees_public_key, \ + storage_keys.locked_secretbox AS userdb_trees_locked_secretbox, \ + storage_keys.sk_nonce AS userdb_trees_sk_nonce, \ + storage_keys.pwhash_opslimit AS userdb_trees_pwhash_opslimit, \ + storage_keys.pwhash_memlimit AS userdb_trees_pwhash_memlimit, \ + storage_keys.pwhash_salt AS userdb_trees_pwhash_salt \ FROM mailboxes \ LEFT OUTER JOIN storage_keys ON mailboxes.user_id = storage_keys.user_id \ WHERE mailboxes.username = '%n' AND mailboxes.domain = '%d' \ @@ -179,8 +179,8 @@ Here is a dovecot SQL query configuration that will work with the sample 8 AS uid, \ 8 AS gid, \ CONCAT('/maildir/', mailboxes.maildir) AS home, \ - storage_keys.enabled AS scrambler_enabled, \ - storage_keys.public_key AS scrambler_public_key, \ + storage_keys.enabled AS trees_enabled, \ + storage_keys.public_key AS trees_public_key, \ CONCAT('*:bytes=', mailboxes.quota) AS quota_rule \ FROM mailboxes \ LEFT OUTER JOIN storage_keys ON mailboxes.user_id = storage_keys.user_id \ @@ -188,14 +188,14 @@ Here is a dovecot SQL query configuration that will work with the sample AND mailboxes.is_active = 1 The odd line `REPLACE('%w', '%%', '%%%%')` is needed to pass the cleartext -password to tofu-scrambler, and allow `%` as a valid password character. +password to TREES, and allow `%` as a valid password character. Argon2 Parameters ---------------------------------------------- There are three recommended levels for the Argon2 parameters, Interactive, -Moderate, and Sensitive. In the case of tofu-scrambler, setting the parameters -at Moderate or Sensitive will make checking email very slow. +Moderate, and Sensitive. In the case of TREES, setting the parameters at +Moderate or Sensitive will make checking email very slow. Interactive: For interactive, online operations, that need to be fast, a reasonable minimum is: diff --git a/bin/tofu-create b/bin/trees-create similarity index 98% rename from bin/tofu-create rename to bin/trees-create index b58ebfa..8c4f885 100755 --- a/bin/tofu-create +++ b/bin/trees-create @@ -2,7 +2,7 @@ # # This is a simple command line script to create a set of values expected -# by tofu_scrambler. Useful for testing. +# by the TREES plugin. Useful for testing. # # NOTE: this requires rbnacl-4.0.0.pre.gem or newer, or Riseup's fork of rbnacl: # @@ -26,7 +26,7 @@ end def usage puts "USAGE:" - puts " tofu-create --password PASSWORD [OPTIONS]" + puts " trees-create --password PASSWORD [OPTIONS]" puts puts "OPTIONS may include:" puts " --opslimit OPSLIMIT -- argon2 ops limit, integer in 3..10, or one of" @@ -202,4 +202,4 @@ class StorageKey end end -main() \ No newline at end of file +main() diff --git a/configure.ac b/configure.ac index 622b775..d635ab8 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,8 @@ AC_PREREQ([2.64]) -AC_INIT([tofu-scrambler],[1.0.0],[],[],[https://0xacab.org/riseuplabs/tofu-scrambler.git]) +AC_INIT([trees],[1.0.0],[https://0xacab.org/riseuplabs/trees/issues], + [trees-plugin],[https://0xacab.org/riseuplabs/trees.git]) -AC_CONFIG_HEADERS([libscrambler-config.h]) +AC_CONFIG_HEADERS([trees-config.h]) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/src/Makefile.am b/src/Makefile.am index 42c6c0c..d8d70c7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,16 +1,16 @@ AM_CPPFLAGS = -I$(top_srcdir)/src -I$(builddir) $(LIBDOVECOT_INCLUDE) -lib_LTLIBRARIES = lib18_scrambler_plugin.la +lib_LTLIBRARIES = lib18_trees_plugin.la -lib18_scrambler_plugin_la_SOURCES = \ - scrambler-common.c \ - scrambler-common.h \ - scrambler-istream.c \ - scrambler-istream.h \ - scrambler-ostream.c \ - scrambler-ostream.h \ - scrambler-plugin.c \ - scrambler-plugin.h +lib18_trees_plugin_la_SOURCES = \ + trees-common.c \ + trees-common.h \ + trees-istream.c \ + trees-istream.h \ + trees-ostream.c \ + trees-ostream.h \ + trees-plugin.c \ + trees-plugin.h -lib18_scrambler_plugin_la_LDFLAGS = \ +lib18_trees_plugin_la_LDFLAGS = \ -shared -rdynamic -avoid-version -module diff --git a/src/scrambler-common.c b/src/trees-common.c similarity index 90% rename from src/scrambler-common.c rename to src/trees-common.c index 4b0d1cc..6f92712 100644 --- a/src/scrambler-common.c +++ b/src/trees-common.c @@ -31,23 +31,23 @@ #include -#include "scrambler-common.h" +#include "trees-common.h" -const unsigned char scrambler_header[] = { 0xee, 0xff, 0xcc }; +const unsigned char trees_header[] = { 0xee, 0xff, 0xcc }; int -scrambler_initialize(void) +trees_initialize(void) { if (sodium_init() < 0) { - i_info("scrambler plugin libsodium failed to initialized."); + i_info("trees plugin libsodium failed to initialized."); return -1; } - i_info("scrambler plugin initialized"); + i_info("trees plugin initialized"); return 0; } const char * -scrambler_read_line_fd(pool_t pool, int fd) +trees_read_line_fd(pool_t pool, int fd) { string_t *buffer = str_new(pool, MAXIMAL_PASSWORD_LENGTH); char *result = str_c_modifiable(buffer); diff --git a/src/scrambler-common.h b/src/trees-common.h similarity index 86% rename from src/scrambler-common.h rename to src/trees-common.h index b7786c2..d8ca434 100644 --- a/src/scrambler-common.h +++ b/src/trees-common.h @@ -20,8 +20,8 @@ * along with this program. If not, see . */ -#ifndef SCRAMBLER_COMMON_H -#define SCRAMBLER_COMMON_H +#ifndef TREES_COMMON_H +#define TREES_COMMON_H #include @@ -30,7 +30,7 @@ #define MIN_VERSION VERSION_ONE #define MAX_VERSION VERSION_ONE -#define MAGIC_SIZE (sizeof(scrambler_header)) +#define MAGIC_SIZE (sizeof(trees_header)) #define VERSION_SIZE (sizeof(uint32_t)) #define HEADER_SIZE (MAGIC_SIZE + VERSION_SIZE) @@ -50,12 +50,12 @@ __typeof__ (b) _b = (b); \ _a > _b ? _a : _b; }) -extern const unsigned char scrambler_header[3]; +extern const unsigned char trees_header[3]; -int scrambler_initialize(void); +int trees_initialize(void); -const char *scrambler_read_line_fd(pool_t pool, int file_descriptor); +const char *trees_read_line_fd(pool_t pool, int file_descriptor); void i_debug_hex(const char *prefix, const unsigned char *data, size_t size); -#endif /* SCRAMBLER_COMMON_H */ +#endif /* TREES_COMMON_H */ diff --git a/src/scrambler-istream.c b/src/trees-istream.c similarity index 75% rename from src/scrambler-istream.c rename to src/trees-istream.c index 6e16c09..b08ff16 100644 --- a/src/scrambler-istream.c +++ b/src/trees-istream.c @@ -28,19 +28,19 @@ #include #include -#include "scrambler-common.h" -#include "scrambler-istream.h" +#include "trees-common.h" +#include "trees-istream.h" -enum scrambler_istream_mode { +enum trees_istream_mode { ISTREAM_MODE_DETECT = 1, ISTREAM_MODE_DECRYPT = 2, ISTREAM_MODE_PLAIN = 3, }; -struct scrambler_istream { +struct trees_istream { struct istream_private istream; - enum scrambler_istream_mode mode; + enum trees_istream_mode mode; uint32_t version; @@ -56,9 +56,9 @@ struct scrambler_istream { }; static ssize_t -scrambler_istream_read_parent(struct scrambler_istream *sstream, - size_t minimal_read_size, - size_t minimal_alloc_size) +trees_istream_read_parent(struct trees_istream *sstream, + size_t minimal_read_size, + size_t minimal_alloc_size) { struct istream_private *stream = &sstream->istream; size_t size; @@ -85,14 +85,14 @@ scrambler_istream_read_parent(struct scrambler_istream *sstream, } static ssize_t -scrambler_istream_read_detect_header(struct scrambler_istream *sstream, - const unsigned char *source) +trees_istream_read_detect_header(struct trees_istream *sstream, + const unsigned char *source) { ssize_t ret; - /* Check for the scrambler header and if so we have an encrypted email that + /* Check for the trees header and if so we have an encrypted email that * we'll try to decrypt. */ - if (!memcmp(scrambler_header, source, MAGIC_SIZE)) { + if (!memcmp(trees_header, source, MAGIC_SIZE)) { /* Yay we have an encrypted mail! Let's get the version of the plugin it * was encrypted for. */ uint32_t version_to_network; @@ -101,7 +101,7 @@ scrambler_istream_read_detect_header(struct scrambler_istream *sstream, sstream->version = ntohl(version_to_network); sstream->mode = ISTREAM_MODE_DECRYPT; if (sstream->private_key == NULL) { - i_error("[scrambler] No private key for decryption."); + i_error("[trees] No private key for decryption."); sstream->istream.istream.stream_errno = EACCES; sstream->istream.istream.eof = TRUE; ret = -1; @@ -109,7 +109,7 @@ scrambler_istream_read_detect_header(struct scrambler_istream *sstream, } if (sstream->version < MIN_VERSION || sstream->version > MAX_VERSION) { - i_error("[scrambler] Unknown version %" PRIu32 ". Supporting %d to %d", + i_error("[trees] Unknown version %" PRIu32 ". Supporting %d to %d", sstream->version, MIN_VERSION, MAX_VERSION); sstream->istream.istream.stream_errno = EACCES; sstream->istream.istream.eof = TRUE; @@ -128,7 +128,7 @@ end: } static ssize_t -scrambler_istream_read_detect(struct scrambler_istream *sstream) +trees_istream_read_detect(struct trees_istream *sstream) { struct istream_private *stream = &sstream->istream; const unsigned char *source; @@ -138,14 +138,14 @@ scrambler_istream_read_detect(struct scrambler_istream *sstream) i_stream_set_max_buffer_size(sstream->istream.parent, MAX_ISTREAM_BUFFER_SIZE); - result = scrambler_istream_read_parent(sstream, MAGIC_SIZE, 0); + result = trees_istream_read_parent(sstream, MAGIC_SIZE, 0); if (result <= 0) { /* Make sure we return an error here. */ result = -1; goto end; } source = i_stream_get_data(stream->parent, &source_size); - result = scrambler_istream_read_detect_header(sstream, source); + result = trees_istream_read_detect_header(sstream, source); if (result < 0) { goto end; } @@ -163,14 +163,14 @@ end: } static ssize_t -scrambler_istream_read_decrypt_chunk(struct scrambler_istream *sstream, - unsigned char *destination, - const unsigned char *source, - size_t source_size) +trees_istream_read_decrypt_chunk(struct trees_istream *sstream, + unsigned char *destination, + const unsigned char *source, + size_t source_size) { #ifdef DEBUG_STREAMS sstream->in_byte_count += source_size; - i_debug("[scrambler] Decrypt chunk source size: %lu", source_size); + i_debug("[trees] Decrypt chunk source size: %lu", source_size); #endif /* Note that we skip the header in the source for decryption. */ @@ -179,7 +179,7 @@ scrambler_istream_read_decrypt_chunk(struct scrambler_istream *sstream, sstream->public_key, sstream->private_key); if (ret != 0) { - i_error("[scrambler] Box seal open failed with %ld", ret); + i_error("[trees] Box seal open failed with %ld", ret); ret = -1; } else { /* We just decrypted that amount of bytes. */ @@ -189,7 +189,7 @@ scrambler_istream_read_decrypt_chunk(struct scrambler_istream *sstream, } static ssize_t -scrambler_istream_read_decrypt(struct scrambler_istream *sstream) +trees_istream_read_decrypt(struct trees_istream *sstream) { struct istream_private *stream = &sstream->istream; const unsigned char *parent_data, *source, *source_end; @@ -197,7 +197,7 @@ scrambler_istream_read_decrypt(struct scrambler_istream *sstream) ssize_t result; size_t source_size; - result = scrambler_istream_read_parent(sstream, ENCRYPTED_CHUNK_SIZE, + result = trees_istream_read_parent(sstream, ENCRYPTED_CHUNK_SIZE, CHUNK_SIZE + stream->pos); if (result <= 0 && result != -1) { return result; @@ -211,7 +211,7 @@ scrambler_istream_read_decrypt(struct scrambler_istream *sstream) while ((source_end - source) >= ENCRYPTED_CHUNK_SIZE) { if (destination_end - destination < CHUNK_SIZE) { - i_error("[scrambler] Decrypting to a destination too small. " + i_error("[trees] Decrypting to a destination too small. " "Expected %ld but remaining %ld. Stopping.", destination_end - destination, source_end - source); @@ -222,7 +222,7 @@ scrambler_istream_read_decrypt(struct scrambler_istream *sstream) /* Decrypt a chunk of our ENCRYPTED_CHUNK_SIZE as we know that we are * expecting at least that amount. */ - result = scrambler_istream_read_decrypt_chunk(sstream, destination, + result = trees_istream_read_decrypt_chunk(sstream, destination, source, ENCRYPTED_CHUNK_SIZE); if (result < 0) { @@ -245,7 +245,7 @@ scrambler_istream_read_decrypt(struct scrambler_istream *sstream) stream->istream.eof = FALSE; if (destination_end - destination < CHUNK_SIZE) { - i_error("[scrambler] At EOF, decrypting to a destination too small. " + i_error("[trees] At EOF, decrypting to a destination too small. " "Expected %ld but remaining %ld", destination_end - destination, source_end - source); @@ -254,7 +254,7 @@ scrambler_istream_read_decrypt(struct scrambler_istream *sstream) return -1; } - result = scrambler_istream_read_decrypt_chunk(sstream, destination, + result = trees_istream_read_decrypt_chunk(sstream, destination, source, source_end - source); if (result < 0) { @@ -282,21 +282,21 @@ scrambler_istream_read_decrypt(struct scrambler_istream *sstream) #ifdef DEBUG_STREAMS sstream->out_byte_count += result; - i_debug("[scrambler] Read decrypt %ld bytes", result); + i_debug("[trees] Read decrypt %ld bytes", result); #endif return result; } static ssize_t -scrambler_istream_read_plain(struct scrambler_istream *sstream) +trees_istream_read_plain(struct trees_istream *sstream) { size_t source_size, copy_size; ssize_t result; const unsigned char *source; struct istream_private *stream = &sstream->istream; - result = scrambler_istream_read_parent(sstream, 1, 0); + result = trees_istream_read_parent(sstream, 1, 0); if (result <= 0) { return result; } @@ -317,13 +317,13 @@ scrambler_istream_read_plain(struct scrambler_istream *sstream) } static ssize_t -scrambler_istream_read(struct istream_private *stream) +trees_istream_read(struct istream_private *stream) { int ret; - struct scrambler_istream *sstream = (struct scrambler_istream *) stream; + struct trees_istream *sstream = (struct trees_istream *) stream; if (sstream->mode == ISTREAM_MODE_DETECT) { - ret = scrambler_istream_read_detect(sstream); + ret = trees_istream_read_detect(sstream); if (ret < 0) { return ret; } @@ -332,9 +332,9 @@ scrambler_istream_read(struct istream_private *stream) /* We've now detected the mode, process it. */ switch (sstream->mode) { case ISTREAM_MODE_DECRYPT: - return scrambler_istream_read_decrypt(sstream); + return trees_istream_read_decrypt(sstream); case ISTREAM_MODE_PLAIN: - return scrambler_istream_read_plain(sstream); + return trees_istream_read_plain(sstream); case ISTREAM_MODE_DETECT: /* Something went terribly wrong. */ assert(0); @@ -345,13 +345,13 @@ scrambler_istream_read(struct istream_private *stream) } static void -scrambler_istream_seek(struct istream_private *stream, uoff_t v_offset, - bool mark) +trees_istream_seek(struct istream_private *stream, uoff_t v_offset, + bool mark) { - struct scrambler_istream *sstream = (struct scrambler_istream *) stream; + struct trees_istream *sstream = (struct trees_istream *) stream; #ifdef DEBUG_STREAMS - i_debug("[scrambler] istream seek %d / %d / %d", + i_debug("[trees] istream seek %d / %d / %d", (int)stream->istream.v_offset, (int)v_offset, (int)mark); #endif @@ -375,7 +375,7 @@ scrambler_istream_seek(struct istream_private *stream, uoff_t v_offset, } static int -scrambler_istream_stat(struct istream_private *stream, bool exact) +trees_istream_stat(struct istream_private *stream, bool exact) { const struct stat *stat; if (i_stream_stat(stream->parent, exact, &stat) < 0) { @@ -386,12 +386,12 @@ scrambler_istream_stat(struct istream_private *stream, bool exact) } static void -scrambler_istream_close(struct iostream_private *stream, bool close_parent) +trees_istream_close(struct iostream_private *stream, bool close_parent) { - struct scrambler_istream *sstream = (struct scrambler_istream *) stream; + struct trees_istream *sstream = (struct trees_istream *) stream; #ifdef DEBUG_STREAMS - i_debug("[scrambler] istream close - %u bytes in / %u bytes out / " + i_debug("[trees] istream close - %u bytes in / %u bytes out / " "%u bytes overhead", sstream->in_byte_count, sstream->out_byte_count, sstream->in_byte_count - sstream->out_byte_count); @@ -403,11 +403,11 @@ scrambler_istream_close(struct iostream_private *stream, bool close_parent) } struct istream * -scrambler_istream_create(struct istream *input, - const unsigned char *public_key, - unsigned char *private_key) +trees_istream_create(struct istream *input, + const unsigned char *public_key, + unsigned char *private_key) { - struct scrambler_istream *sstream = i_new(struct scrambler_istream, 1); + struct trees_istream *sstream = i_new(struct trees_istream, 1); sstream->mode = ISTREAM_MODE_DETECT; @@ -416,11 +416,11 @@ scrambler_istream_create(struct istream *input, sstream->last_chunk_read = 0; - sstream->istream.iostream.close = scrambler_istream_close; + sstream->istream.iostream.close = trees_istream_close; sstream->istream.max_buffer_size = input->real_stream->max_buffer_size; - sstream->istream.read = scrambler_istream_read; - sstream->istream.seek = scrambler_istream_seek; - sstream->istream.stat = scrambler_istream_stat; + sstream->istream.read = trees_istream_read; + sstream->istream.seek = trees_istream_seek; + sstream->istream.stat = trees_istream_stat; sstream->istream.istream.readable_fd = FALSE; sstream->istream.istream.blocking = input->blocking; diff --git a/src/scrambler-istream.h b/src/trees-istream.h similarity index 77% rename from src/scrambler-istream.h rename to src/trees-istream.h index f720d90..6a7afd8 100644 --- a/src/scrambler-istream.h +++ b/src/trees-istream.h @@ -20,13 +20,13 @@ * along with this program. If not, see . */ -#ifndef SCRAMBLER_ISTREAM_H -#define SCRAMBLER_ISTREAM_H +#ifndef TREES_ISTREAM_H +#define TREES_ISTREAM_H #include -struct istream *scrambler_istream_create(struct istream *input, - const unsigned char *public_key, - unsigned char *private_key); +struct istream *trees_istream_create(struct istream *input, + const unsigned char *public_key, + unsigned char *private_key); -#endif /* SCRAMBLER_ISTREAM_H */ +#endif /* TREES_ISTREAM_H */ diff --git a/src/scrambler-ostream.c b/src/trees-ostream.c similarity index 74% rename from src/scrambler-ostream.c rename to src/trees-ostream.c index d558dd2..dcbc422 100644 --- a/src/scrambler-ostream.c +++ b/src/trees-ostream.c @@ -30,11 +30,11 @@ #include -#include "scrambler-common.h" -#include "scrambler-ostream.h" +#include "trees-common.h" +#include "trees-ostream.h" -struct scrambler_ostream { +struct trees_ostream { struct ostream_private ostream; uint32_t version; @@ -52,13 +52,13 @@ struct scrambler_ostream { }; static ssize_t -scrambler_ostream_send_header(struct scrambler_ostream *sstream) +trees_ostream_send_header(struct trees_ostream *sstream) { char header[HEADER_SIZE]; uint32_t version_to_host; /* First set the header magic number. */ - memcpy(header, scrambler_header, MAGIC_SIZE); + memcpy(header, trees_header, MAGIC_SIZE); /* Then, put in the version. */ version_to_host = htonl(sstream->version); memcpy(header + MAGIC_SIZE, &version_to_host, VERSION_SIZE); @@ -73,8 +73,8 @@ scrambler_ostream_send_header(struct scrambler_ostream *sstream) } static ssize_t -scrambler_ostream_send_chunk(struct scrambler_ostream *sstream, - const unsigned char *chunk, size_t chunk_size) +trees_ostream_send_chunk(struct trees_ostream *sstream, + const unsigned char *chunk, size_t chunk_size) { int ret; /* Extra protection here against overflow. Maybe too agressive! */ @@ -101,13 +101,13 @@ scrambler_ostream_send_chunk(struct scrambler_ostream *sstream, } static ssize_t -scrambler_ostream_sendv(struct ostream_private *stream, - const struct const_iovec *iov, unsigned int iov_count) +trees_ostream_sendv(struct ostream_private *stream, + const struct const_iovec *iov, unsigned int iov_count) { size_t chunk_size; ssize_t result = 0, encrypt_result = 0; const unsigned char *source, *source_end; - struct scrambler_ostream *sstream = (struct scrambler_ostream *) stream; + struct trees_ostream *sstream = (struct trees_ostream *) stream; for (unsigned int index = 0; index < iov_count; index++) { source = iov[index].iov_base; @@ -123,7 +123,7 @@ scrambler_ostream_sendv(struct ostream_private *stream, sstream->chunk_buffer_size += chunk_size; if (sstream->chunk_buffer_size == CHUNK_SIZE) { - encrypt_result = scrambler_ostream_send_chunk(sstream, + encrypt_result = trees_ostream_send_chunk(sstream, sstream->chunk_buffer, CHUNK_SIZE); if (encrypt_result < 0) { @@ -132,7 +132,7 @@ scrambler_ostream_sendv(struct ostream_private *stream, sstream->chunk_buffer_size = 0; } } else { - encrypt_result = scrambler_ostream_send_chunk(sstream, source, + encrypt_result = trees_ostream_send_chunk(sstream, source, CHUNK_SIZE); if (encrypt_result < 0) { return encrypt_result; @@ -149,26 +149,26 @@ scrambler_ostream_sendv(struct ostream_private *stream, #ifdef DEBUG_STREAMS sstream->in_byte_count += result; - i_debug("[scrambler] ostream send (%ld)", result); + i_debug("[trees] ostream send (%ld)", result); #endif return result; } static int -scrambler_ostream_flush(struct ostream_private *stream) +trees_ostream_flush(struct ostream_private *stream) { ssize_t result = 0; - struct scrambler_ostream *sstream = (struct scrambler_ostream *) stream; + struct trees_ostream *sstream = (struct trees_ostream *) stream; if (sstream->flushed) { goto end; } - result = scrambler_ostream_send_chunk(sstream, sstream->chunk_buffer, + result = trees_ostream_send_chunk(sstream, sstream->chunk_buffer, sstream->chunk_buffer_size); if (result < 0) { - i_error("[scrambler] Error sending last chunk on close"); + i_error("[trees] Error sending last chunk on close"); goto end; } sstream->chunk_buffer_size = 0; @@ -183,19 +183,19 @@ scrambler_ostream_flush(struct ostream_private *stream) end: #ifdef DEBUG_STREAMS - i_debug("[scrambler] ostream flush (%ld)", result); + i_debug("[trees] ostream flush (%ld)", result); #endif return result; } static void -scrambler_ostream_close(struct iostream_private *stream, - bool close_parent) +trees_ostream_close(struct iostream_private *stream, + bool close_parent) { - struct scrambler_ostream *sstream = (struct scrambler_ostream *) stream; + struct trees_ostream *sstream = (struct trees_ostream *) stream; #ifdef DEBUG_STREAMS - i_debug("[scrambler] ostream close - %u bytes in / %u bytes out / " + i_debug("[trees] ostream close - %u bytes in / %u bytes out / " "%u bytes overhead", sstream->in_byte_count, sstream->out_byte_count, sstream->out_byte_count - sstream->in_byte_count); @@ -207,11 +207,11 @@ scrambler_ostream_close(struct iostream_private *stream, } struct ostream * -scrambler_ostream_create(struct ostream *output, - const unsigned char *public_key, - uint32_t version) +trees_ostream_create(struct ostream *output, + const unsigned char *public_key, + uint32_t version) { - struct scrambler_ostream *sstream = i_new(struct scrambler_ostream, 1); + struct trees_ostream *sstream = i_new(struct trees_ostream, 1); struct ostream *result; sstream->public_key = public_key; @@ -220,9 +220,9 @@ scrambler_ostream_create(struct ostream *output, sstream->chunk_buffer_size = 0; sstream->flushed = 0; - sstream->ostream.iostream.close = scrambler_ostream_close; - sstream->ostream.sendv = scrambler_ostream_sendv; - sstream->ostream.flush = scrambler_ostream_flush; + sstream->ostream.iostream.close = trees_ostream_close; + sstream->ostream.sendv = trees_ostream_sendv; + sstream->ostream.flush = trees_ostream_flush; #ifdef DEBUG_STREAMS sstream->in_byte_count = 0; @@ -231,8 +231,8 @@ scrambler_ostream_create(struct ostream *output, result = o_stream_create(&sstream->ostream, output, o_stream_get_fd(output)); - if (scrambler_ostream_send_header(sstream) < 0) { - i_error("[scrambler] Unable to create ostream"); + if (trees_ostream_send_header(sstream) < 0) { + i_error("[trees] Unable to create ostream"); return NULL; } diff --git a/src/scrambler-ostream.h b/src/trees-ostream.h similarity index 77% rename from src/scrambler-ostream.h rename to src/trees-ostream.h index 90a1aae..3846aa7 100644 --- a/src/scrambler-ostream.h +++ b/src/trees-ostream.h @@ -20,13 +20,13 @@ * along with this program. If not, see . */ -#ifndef SCRAMBLER_OSTREAM_H -#define SCRAMBLER_OSTREAM_H +#ifndef TREES_OSTREAM_H +#define TREES_OSTREAM_H #include -struct ostream *scrambler_ostream_create(struct ostream *parent_ostream, - const unsigned char *public_key, - uint32_t version); +struct ostream *trees_ostream_create(struct ostream *parent_ostream, + const unsigned char *public_key, + uint32_t version); -#endif /* SCRAMBLER_OSTREAM_H */ +#endif /* TREES_OSTREAM_H */ diff --git a/src/scrambler-plugin.c b/src/trees-plugin.c similarity index 64% rename from src/scrambler-plugin.c rename to src/trees-plugin.c index 25cc24b..8fe131e 100644 --- a/src/scrambler-plugin.c +++ b/src/trees-plugin.c @@ -40,19 +40,19 @@ #include -#include "scrambler-plugin.h" -#include "scrambler-common.h" -#include "scrambler-ostream.h" -#include "scrambler-istream.h" +#include "trees-plugin.h" +#include "trees-common.h" +#include "trees-ostream.h" +#include "trees-istream.h" -#define SCRAMBLER_CONTEXT(obj) \ - MODULE_CONTEXT(obj, scrambler_storage_module) -#define SCRAMBLER_MAIL_CONTEXT(obj) \ - MODULE_CONTEXT(obj, scrambler_mail_module) -#define SCRAMBLER_USER_CONTEXT(obj) \ - MODULE_CONTEXT(obj, scrambler_user_module) +#define TREES_CONTEXT(obj) \ + MODULE_CONTEXT(obj, trees_storage_module) +#define TREES_MAIL_CONTEXT(obj) \ + MODULE_CONTEXT(obj, trees_mail_module) +#define TREES_USER_CONTEXT(obj) \ + MODULE_CONTEXT(obj, trees_user_module) -struct scrambler_user { +struct trees_user { /* Dovecot module context. */ union mail_user_module_context module_ctx; @@ -71,25 +71,25 @@ struct scrambler_user { unsigned char private_key[crypto_box_SECRETKEYBYTES]; }; -const char *scrambler_plugin_version = DOVECOT_ABI_VERSION; +const char *trees_plugin_version = DOVECOT_ABI_VERSION; -static MODULE_CONTEXT_DEFINE_INIT(scrambler_storage_module, +static MODULE_CONTEXT_DEFINE_INIT(trees_storage_module, &mail_storage_module_register); -static MODULE_CONTEXT_DEFINE_INIT(scrambler_mail_module, +static MODULE_CONTEXT_DEFINE_INIT(trees_mail_module, &mail_module_register); -static MODULE_CONTEXT_DEFINE_INIT(scrambler_user_module, +static MODULE_CONTEXT_DEFINE_INIT(trees_user_module, &mail_user_module_register); static const char * -scrambler_get_string_setting(struct mail_user *user, const char *name) +trees_get_string_setting(struct mail_user *user, const char *name) { return mail_user_plugin_getenv(user, name); } static unsigned long long int -scrambler_get_ullong_setting(struct mail_user *user, const char *name) +trees_get_ullong_setting(struct mail_user *user, const char *name) { - const char *value = scrambler_get_string_setting(user, name); + const char *value = trees_get_string_setting(user, name); if (value == NULL) { return ULLONG_MAX; } @@ -97,9 +97,9 @@ scrambler_get_ullong_setting(struct mail_user *user, const char *name) } static int -scrambler_get_integer_setting(struct mail_user *user, const char *name) +trees_get_integer_setting(struct mail_user *user, const char *name) { - const char *value = scrambler_get_string_setting(user, name); + const char *value = trees_get_string_setting(user, name); if (value == NULL) { return -1; } @@ -107,12 +107,12 @@ scrambler_get_integer_setting(struct mail_user *user, const char *name) } static int -scrambler_get_user_hexdata(struct mail_user *user, const char *param, - unsigned char *out, size_t out_len) +trees_get_user_hexdata(struct mail_user *user, const char *param, + unsigned char *out, size_t out_len) { const char *hex_str; - hex_str = scrambler_get_string_setting(user, param); + hex_str = trees_get_string_setting(user, param); if (hex_str == NULL) { goto error; } @@ -121,7 +121,7 @@ scrambler_get_user_hexdata(struct mail_user *user, const char *param, user->error = p_strdup_printf(user->pool, "Unable to convert %s for user %s.", param, user->username); - i_error("[scrambler] Failing to hex2bin for %s", param); + i_error("[trees] Failing to hex2bin for %s", param); goto error; } @@ -132,8 +132,8 @@ error: } static int -scrambler_get_private_key(struct mail_user *user, - struct scrambler_user *suser) +trees_get_private_key(struct mail_user *user, + struct trees_user *suser) { int have_salt, password_fd; unsigned long long opslimit, memlimit; @@ -148,10 +148,10 @@ scrambler_get_private_key(struct mail_user *user, const char *password; /* Get the user password that we'll use to . */ - password = scrambler_get_string_setting(user, "scrambler_password"); - password_fd = scrambler_get_integer_setting(user, "scrambler_password_fd"); + password = trees_get_string_setting(user, "trees_password"); + password_fd = trees_get_integer_setting(user, "trees_password_fd"); if (password == NULL && password_fd >= 0) { - password = scrambler_read_line_fd(user->pool, password_fd); + password = trees_read_line_fd(user->pool, password_fd); } /* No password means that we are receiving email and have no access to the @@ -161,32 +161,32 @@ scrambler_get_private_key(struct mail_user *user, } /* Get the nonce. */ - if (scrambler_get_user_hexdata(user, "scrambler_sk_nonce", + if (trees_get_user_hexdata(user, "trees_sk_nonce", sk_nonce, sizeof(sk_nonce))) { user->error = p_strdup_printf(user->pool, "Unable to find nonce value for user %s.", user->username); - i_error("[scrambler] Unable to get sk_nonce."); + i_error("[trees] Unable to get sk_nonce."); goto error; } /* Get the opslimit and memlimit. */ - opslimit = scrambler_get_ullong_setting(user, "scrambler_pwhash_opslimit"); + opslimit = trees_get_ullong_setting(user, "trees_pwhash_opslimit"); if (opslimit == ULLONG_MAX) { - i_error("[scrambler] Bad pwhash_opslimit value."); + i_error("[trees] Bad pwhash_opslimit value."); goto error; } - memlimit = scrambler_get_ullong_setting(user, "scrambler_pwhash_memlimit"); + memlimit = trees_get_ullong_setting(user, "trees_pwhash_memlimit"); if (memlimit == ULLONG_MAX) { - i_error("[scrambler] Bad pwhash_memlimit value."); + i_error("[trees] Bad pwhash_memlimit value."); goto error; } - /* Get the scrambler user salt. It's possible that it's not available. */ - have_salt = scrambler_get_user_hexdata(user, "scrambler_pwhash_salt", + /* Get the trees user salt. It's possible that it's not available. */ + have_salt = trees_get_user_hexdata(user, "trees_pwhash_salt", pw_salt, sizeof(pw_salt)); if (have_salt == -1) { - i_error("[scrambler] Unable to get the pwhash_salt."); + i_error("[trees] Unable to get the pwhash_salt."); goto end; } @@ -199,19 +199,19 @@ scrambler_get_private_key(struct mail_user *user, user->error = p_strdup_printf(user->pool, "Unable to derive private key for user %s.", user->username); - i_error("[scrambler] pwhash failed for %s", user->username); + i_error("[trees] pwhash failed for %s", user->username); goto error; } - if (scrambler_get_user_hexdata(user, "scrambler_locked_secretbox", + if (trees_get_user_hexdata(user, "trees_locked_secretbox", secretbox, sizeof(secretbox))) { - i_error("[scrambler] Unable to get locked_secretbox"); + i_error("[trees] Unable to get locked_secretbox"); goto error; } if (crypto_secretbox_open_easy(suser->private_key, secretbox, sizeof(secretbox), sk_nonce, sk) < 0) { - i_error("[scrambler] Unable to open secretbox."); + i_error("[trees] Unable to open secretbox."); goto error; } /* Got the private key! */ @@ -225,20 +225,20 @@ error: } static void -scrambler_mail_user_created(struct mail_user *user) +trees_mail_user_created(struct mail_user *user) { int version; struct mail_user_vfuncs *v = user->vlast; - struct scrambler_user *suser; + struct trees_user *suser; - suser = p_new(user->pool, struct scrambler_user, 1); + suser = p_new(user->pool, struct trees_user, 1); memset(suser, 0, sizeof(*suser)); suser->module_ctx.super = *v; user->vlast = &suser->module_ctx.super; - /* Does this user should use the scrambler or not? */ - suser->enabled = scrambler_get_integer_setting(user, "scrambler_enabled"); + /* Does this user should use the trees or not? */ + suser->enabled = trees_get_integer_setting(user, "trees_enabled"); if (suser->enabled == -1 || suser->enabled == 0) { /* Not present means disabled. Stop right now because we won't use * anything of this plugin for the user. */ @@ -247,19 +247,19 @@ scrambler_mail_user_created(struct mail_user *user) } /* Get plugin version that the user is configured for. */ - version = scrambler_get_integer_setting(user, "scrambler_version"); + version = trees_get_integer_setting(user, "trees_version"); if (version < MIN_VERSION || version > MAX_VERSION) { - i_error("[scrambler] Bad version value."); + i_error("[trees] Bad version value."); goto end; } suser->version = (uint32_t) version; /* Getting user public key. Without it, we can't do much so error if we * can't find it. */ - if (scrambler_get_user_hexdata(user, "scrambler_public_key", + if (trees_get_user_hexdata(user, "trees_public_key", suser->public_key, sizeof(suser->public_key))) { - i_error("[scrambler] Unable to find public_key"); + i_error("[trees] Unable to find public_key"); goto end; } suser->public_key_set = 1; @@ -269,21 +269,21 @@ scrambler_mail_user_created(struct mail_user *user) * email. If we are successful at getting the private key, this flag will * be set to 1. */ suser->private_key_set = 0; - if (scrambler_get_private_key(user, suser) < 0) { + if (trees_get_private_key(user, suser) < 0) { goto end; } end: - MODULE_CONTEXT_SET(user, scrambler_user_module, suser); + MODULE_CONTEXT_SET(user, trees_user_module, suser); } static int -scrambler_mail_save_begin(struct mail_save_context *context, - struct istream *input) +trees_mail_save_begin(struct mail_save_context *context, + struct istream *input) { struct mailbox *box = context->transaction->box; - union mailbox_module_context *mbox = SCRAMBLER_CONTEXT(box); - struct scrambler_user *suser = SCRAMBLER_USER_CONTEXT(box->storage->user); + union mailbox_module_context *mbox = TREES_CONTEXT(box); + struct trees_user *suser = TREES_USER_CONTEXT(box->storage->user); struct ostream *output; if (mbox->super.save_begin(context, input) < 0) { @@ -296,21 +296,21 @@ scrambler_mail_save_begin(struct mail_save_context *context, if (!suser->public_key_set) { /* No public key for a user that have the plugin enabled is not good. */ - i_error("[scrambler] User public key not found. Skipping."); + i_error("[trees] User public key not found. Skipping."); goto end; } // TODO: find a better solution for this. this currently works, because - // there is only one other ostream (zlib) in the setup. the scrambler should + // there is only one other ostream (zlib) in the setup. the trees should // be added to the other end of the ostream chain, not to the // beginning (the usual way). if (context->data.output->real_stream->parent == NULL) { - output = scrambler_ostream_create(context->data.output, + output = trees_ostream_create(context->data.output, suser->public_key, suser->version); o_stream_unref(&context->data.output); context->data.output = output; } else { - output = scrambler_ostream_create(context->data.output->real_stream->parent, + output = trees_ostream_create(context->data.output->real_stream->parent, suser->public_key, suser->version); o_stream_unref(&context->data.output->real_stream->parent); context->data.output->real_stream->parent = output; @@ -321,7 +321,7 @@ end: } static void -scrambler_mailbox_allocated(struct mailbox *box) +trees_mailbox_allocated(struct mailbox *box) { struct mailbox_vfuncs *v = box->vlast; union mailbox_module_context *mbox; @@ -331,28 +331,28 @@ scrambler_mailbox_allocated(struct mailbox *box) mbox->super = *v; box->vlast = &mbox->super; - MODULE_CONTEXT_SET_SELF(box, scrambler_storage_module, mbox); + MODULE_CONTEXT_SET_SELF(box, trees_storage_module, mbox); if ((class_flags & MAIL_STORAGE_CLASS_FLAG_OPEN_STREAMS) == 0) { - v->save_begin = scrambler_mail_save_begin; + v->save_begin = trees_mail_save_begin; } } static int -scrambler_istream_opened(struct mail *_mail, struct istream **stream) +trees_istream_opened(struct mail *_mail, struct istream **stream) { unsigned char *private_key = NULL; struct mail_private *mail = (struct mail_private *)_mail; struct mail_user *user = _mail->box->storage->user; - struct scrambler_user *suser = SCRAMBLER_USER_CONTEXT(user); - union mail_module_context *mmail = SCRAMBLER_MAIL_CONTEXT(mail); + struct trees_user *suser = TREES_USER_CONTEXT(user); + union mail_module_context *mmail = TREES_MAIL_CONTEXT(mail); struct istream *input; input = *stream; if (suser->private_key_set) { private_key = suser->private_key; } - *stream = scrambler_istream_create(input, suser->public_key, + *stream = trees_istream_create(input, suser->public_key, private_key); i_stream_unref(&input); @@ -360,7 +360,7 @@ scrambler_istream_opened(struct mail *_mail, struct istream **stream) } static void -scrambler_mail_allocated(struct mail *_mail) +trees_mail_allocated(struct mail *_mail) { struct mail_private *mail = (struct mail_private *)_mail; struct mail_vfuncs *v = mail->vlast; @@ -370,29 +370,29 @@ scrambler_mail_allocated(struct mail *_mail) mmail->super = *v; mail->vlast = &mmail->super; - v->istream_opened = scrambler_istream_opened; + v->istream_opened = trees_istream_opened; - MODULE_CONTEXT_SET_SELF(mail, scrambler_mail_module, mmail); + MODULE_CONTEXT_SET_SELF(mail, trees_mail_module, mmail); } -static struct mail_storage_hooks scrambler_mail_storage_hooks = { - .mail_user_created = scrambler_mail_user_created, - .mailbox_allocated = scrambler_mailbox_allocated, - .mail_allocated = scrambler_mail_allocated +static struct mail_storage_hooks trees_mail_storage_hooks = { + .mail_user_created = trees_mail_user_created, + .mailbox_allocated = trees_mailbox_allocated, + .mail_allocated = trees_mail_allocated }; void -scrambler_plugin_init(struct module *module) +trees_plugin_init(struct module *module) { - if (scrambler_initialize() < 0) { + if (trees_initialize() < 0) { /* Don't hook anything has we weren't able to initialize ourself. */ return; } - mail_storage_hooks_add(module, &scrambler_mail_storage_hooks); + mail_storage_hooks_add(module, &trees_mail_storage_hooks); } void -scrambler_plugin_deinit(void) +trees_plugin_deinit(void) { - mail_storage_hooks_remove(&scrambler_mail_storage_hooks); + mail_storage_hooks_remove(&trees_mail_storage_hooks); } diff --git a/src/scrambler-plugin.h b/src/trees-plugin.h similarity index 85% rename from src/scrambler-plugin.h rename to src/trees-plugin.h index c6169df..3074ad3 100644 --- a/src/scrambler-plugin.h +++ b/src/trees-plugin.h @@ -20,10 +20,10 @@ * along with this program. If not, see . */ -#ifndef SCRAMBLER_PLUGIN_H -#define SCRAMBLER_PLUGIN_H +#ifndef TREES_PLUGIN_H +#define TREES_PLUGIN_H -void scrambler_plugin_init(struct module *module); -void scrambler_plugin_deinit(void); +void trees_plugin_init(struct module *module); +void trees_plugin_deinit(void); -#endif /* SCRAMBLER_PLUGIN_H */ +#endif /* TREES_PLUGIN_H */