Skip to content

Commit

Permalink
io_compress, net_imap: Add support for DEFLATE compression.
Browse files Browse the repository at this point in the history
* io_compress: Add I/O module for RFC 1951 DEFLATE compression.
* net_imap: Add RFC 4978 COMPRESS=DEFLATE support on top of that.
  • Loading branch information
InterLinked1 committed Apr 10, 2024
1 parent d0e17f2 commit 32c6323
Show file tree
Hide file tree
Showing 10 changed files with 514 additions and 12 deletions.
57 changes: 57 additions & 0 deletions bbs/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,50 @@ static int io_transform_store(struct bbs_io_transformations *trans, struct bbs_i
return -1;
}

static int __bbs_io_transform_possible(struct bbs_io_transformations *trans, enum bbs_io_transform_type type, int warn)
{
if (bbs_io_transform_active(trans, type)) {
if (warn) {
bbs_error("Transformation %d already active, declining to set up duplicate transformation\n", type);
}
return 0;
}

/* TLS compression is disabled, so we don't need to worry about rejecting TRANSFORM_DEFLATE_COMPRESSION
* if that were already to be active (as normally, that would conflict). */

/* XXX Ideally, ordering constraints would be specified in the modules themselves,
* but since this involves both of them, just put it here for now: */
if (type == TRANSFORM_TLS_ENCRYPTION) {
if (bbs_io_transform_active(trans, TRANSFORM_DEFLATE_COMPRESSION)) {
/* Since I/O transformations are pushed onto a stack of file descriptors, effectively,
* but TLS must happen after compression, it is too late to begin encryption.
* The current I/O transformation architecture doesn't really us to add transformations
* underneath existing ones. */
if (warn) {
bbs_warning("Can't enable encryption after compression has already been enabled, enable encryption prior to compression instead\n");
}
return 0;
}
}
return 1;
}

int bbs_io_transform_possible(struct bbs_io_transformations *trans, enum bbs_io_transform_type type)
{
return __bbs_io_transform_possible(trans, type, 0);
}

int bbs_io_transform_setup(struct bbs_io_transformations *trans, enum bbs_io_transform_type type, enum bbs_io_transform_dir direction, int *rfd, int *wfd, const void *arg)
{
int res;
void *data = NULL;
struct bbs_io_transformer *t;

if (!__bbs_io_transform_possible(trans, type, 1)) {
return -1;
}

RWLIST_RDLOCK(&transformers);
if (!io_transform_slots_free(trans)) {
RWLIST_UNLOCK(&transformers);
Expand Down Expand Up @@ -225,6 +263,25 @@ int bbs_io_transform_setup(struct bbs_io_transformations *trans, enum bbs_io_tra
return res;
}

int bbs_io_transform_active(struct bbs_io_transformations *trans, enum bbs_io_transform_type type)
{
int i, active = 0;

RWLIST_RDLOCK(&transformers);
for (i = 0; i < MAX_IO_TRANSFORMS; i++) {
if (trans->transformations[i].data) {
struct bbs_io_transformer *t = trans->transformations[i].transformer;
if (t->type == type) {
active = 1;
break;
}
}
}
RWLIST_UNLOCK(&transformers);

return active;
}

int bbs_io_transform_query(struct bbs_io_transformations *trans, enum bbs_io_transform_type type, int query, void *data)
{
int i;
Expand Down
2 changes: 1 addition & 1 deletion bbs/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -2094,7 +2094,7 @@ int bbs_node_starttls(struct bbs_node *node)
return 1;
}

res = bbs_io_transform_setup(&node->trans, TRANSFORM_TLS_ENCRYPTION, TRANSFORM_SERVER, &node->rfd, &node->wfd, NULL);
res = bbs_io_transform_setup(&node->trans, TRANSFORM_TLS_ENCRYPTION, TRANSFORM_SERVER, &node->rfd, &node->wfd, NULL);
if (res) {
/* If TLS setup fails, it's probably garbage traffic and safe to penalize: */
if (node) {
Expand Down
25 changes: 23 additions & 2 deletions include/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

enum bbs_io_transform_type {
TRANSFORM_TLS_ENCRYPTION = 0, /*!< TLS encryption/decryption */
TRANSFORM_ZLIB_COMPRESSION = 1, /*!< zlib compression/decompression */
TRANSFORM_DEFLATE_COMPRESSION = 1, /*!< zlib compression/decompression */
};

/* Number of transform types in above enum + a few more if we allow other kinds */
Expand All @@ -35,7 +35,9 @@ enum bbs_io_transform_dir {
#define TRANSFORM_CLIENT (TRANSFORM_CLIENT_TX | TRANSFORM_CLIENT_RX)
#define TRANSFORM_SERVER_CLIENT_TX_RX (TRANSFORM_SERVER_TX | TRANSFORM_SERVER_RX | TRANSFORM_CLIENT_TX | TRANSFORM_CLIENT_RX)

#define TRANSFORM_QUERY_TLS_REUSE 0
#define TRANSFORM_QUERY_TLS_REUSE 0 /* TRANSFORM_TLS_ENCRYPTION: Get whether SSL session was reused, using arg as output */
#define TRANSFORM_QUERY_COMPRESSION_FLUSH 1 /* TRANSFORM_DEFLATE_COMPRESSION: Do a full flush (arg not used) */
#define TRANSFORM_QUERY_SET_COMPRESSION_LEVEL 2 /* TRANSFORM_DEFLATE_COMPRESSION: Set compression level (0 = none, 9 = max, slowest), using arg as input */

struct bbs_io_transformer;

Expand Down Expand Up @@ -73,6 +75,15 @@ int bbs_io_named_transformer_available(const char *name);
/*! \brief Check if a suitable transformer is available */
int bbs_io_transformer_available(enum bbs_io_transform_type transform_type);

/*!
* \brief Check whether a transformation is possible, given what transformations are already running
* \param trans
* \param type
* \retval 1 transformation allowed
* \retval 0 not allowed, and calling bbs_io_transform_setup will fail
*/
int bbs_io_transform_possible(struct bbs_io_transformations *trans, enum bbs_io_transform_type type);

/*!
* \brief Begin using a transformer. This action is permanent (only bbs_io_teardown_all_transformers will end transformation)
* \param trans
Expand All @@ -85,6 +96,15 @@ int bbs_io_transformer_available(enum bbs_io_transform_type transform_type);
*/
int bbs_io_transform_setup(struct bbs_io_transformations *trans, enum bbs_io_transform_type type, enum bbs_io_transform_dir direction, int *rfd, int *wfd, const void *arg);

/*!
* \brief Check whether a transformation is currently active
* \param trans
* \param type
* \retval 1 if currently active, 0 if not
* \note For checking if TLS is active on a node, use node->secure instead
*/
int bbs_io_transform_active(struct bbs_io_transformations *trans, enum bbs_io_transform_type type);

/*!
* \brief Read and/or write a setting while a transformation is active
* \param trans
Expand All @@ -105,5 +125,6 @@ int bbs_io_transform_query(struct bbs_io_transformations *trans, enum bbs_io_tra
void bbs_io_teardown_all_transformers(struct bbs_io_transformations *trans);

#define ssl_available() (bbs_io_transformer_available(TRANSFORM_TLS_ENCRYPTION))
#define deflate_compression_available() (bbs_io_transformer_available(TRANSFORM_DEFLATE_COMPRESSION))

#endif /* _BBS_IO_TRANSFORM */
4 changes: 4 additions & 0 deletions io/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ $(DEPENDS):
@echo " [LD] $^ -> $@"
$(CC) -shared -fPIC -o $(basename $^).so $^

io_compress.so : io_compress.o
@echo " [LD] $^ -> $@"
$(CC) -shared -fPIC -o $(basename $^).so $^ -lz

io_tls.so : io_tls.o
@echo " [LD] $^ -> $@"
$(CC) -shared -fPIC -o $(basename $^).so $^ -lssl -lcrypto
Expand Down
Loading

0 comments on commit 32c6323

Please sign in to comment.