Skip to content

Commit

Permalink
Update and extend plugin documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
simonrob committed Dec 21, 2023
1 parent 6b9abab commit 6e3c66a
Showing 1 changed file with 21 additions and 6 deletions.
27 changes: 21 additions & 6 deletions plugins/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Email OAuth 2.0 Proxy plugins
Plugins are a semi-experimental Email OAuth 2.0 Proxy feature that enables the use of separate scripts to modify IMAP/POP/SMTP commands when they are received from the client or server before passing through to the other side of the connection.
Plugins are an advanced Email OAuth 2.0 Proxy feature that enable the use of separate scripts to modify IMAP/POP/SMTP commands when they are received from the client or server before passing through to the other side of the connection.
This allows a wide range of additional capabilities or triggers to be added the proxy, as demonstrated in the examples below.


Expand All @@ -12,10 +12,6 @@ As a result, it is not specific to IMAP, POP or SMTP, and can be used with any t
- [`IMAPCleanO365ATPLinks`](plugins/IMAPCleanO365ATPLinks.py): An example IMAP plugin that looks for Office 365 Advanced Threat Protection links (also known as Safe Links in Microsoft Defender for Office 365) and replaces them with their original values (i.e., removing the redirect).
As with most of the proxy's plugins, it would be more efficient to handle this on the server side (i.e., by disabling link modification), but this is not always possible.

- [`IMAPDisableDeflateCompression`](plugins/IMAPDisableDeflateCompression.py): An example IMAP plugin that looks for client requests to enable compression (RFC 1951 and 4978) and responds with NO every time, so that other plugins can continue to intercept requests.
Place this plugin before any others if you use a client that automatically tries to enable compression when it finds `COMPRESS=DEFLATE` in a `CAPABILITY` response.
An alternative option here if you do not need to actually edit messages is to keep compression enabled, but decompress within the plugin – see [`IMAPDecodeDeflateCompression`](plugins/IMAPDecodeDeflateCompression.py).

- [`IMAPDecodeDeflateCompression`](plugins/IMAPDecodeDeflateCompression.py): An example IMAP plugin that looks for client requests to enable compression (RFC 1951 and 4978) and, unlike [`IMAPDisableDeflateCompression`](plugins/IMAPDisableDeflateCompression.py), permits compression but decompresses messages within the plugin.
This allows monitoring and editing of compressed incoming and outgoing communication, but only within this plugin, not any others (and as a result only other deflate-aware plugins can be chained).
An alternative option and further improvement can be found in [`IMAPDeflateCompressionRemoteEnabler`](plugins/IMAPDeflateCompressionRemoteEnabler.py).
Expand All @@ -24,10 +20,21 @@ An alternative option and further improvement can be found in [`IMAPDeflateCompr
and 4978) and, unlike [`IMAPDecodeDeflateCompression`](plugins/IMAPDecodeDeflateCompression.py), handles this entirely within the plugin, keeping an uncompressed channel to the client, but enabling compressed communication with the server.
Place this plugin at the end of the chain in the proxy's configuration file.

- [`IMAPDisableDeflateCompression`](plugins/IMAPDisableDeflateCompression.py): An example IMAP plugin that looks for client requests to enable compression (RFC 1951 and 4978) and responds with `NO` every time, so that other plugins can continue to intercept requests.
Place this plugin before any others if you use a client that automatically tries to enable compression when it finds `COMPRESS=DEFLATE` in a `CAPABILITY` response.
An alternative option here if you do not need to actually edit messages is to keep compression enabled, but decompress within the plugin – see [`IMAPDecodeDeflateCompression`](plugins/IMAPDecodeDeflateCompression.py).

- [`IMAPFixO365SearchQuirks`](plugins/IMAPFixO365SearchQuirks.py): An example IMAP plugin that modifies search strings to fix O365's inability to handle uppercase characters in searches.
The plugin also changes `BODY` searches to `TEXT` to prompt O365 to return flags in the results.
Note that no detection of whether the remote server is actually O365 takes place.

- [`IMAPIgnoreSentMessageUpload`](plugins/IMAPIgnoreSentMessageUpload.py): An example IMAP plugin that accepts client requests to upload sent messages to an IMAP mailbox, but silently discards them without sending to the server.
This plugin helps avoid message duplication for servers that automatically place messages sent via SMTP into the relevant IMAP mailbox.
Note that many clients are aware of this behaviour and provide an option to not upload sent messages – if this is available it is a much more efficient solution than adding a proxy plugin.

- [`/IMAPRegexContentReplacer`](plugins/IMAPRegexContentReplacer.py): An example IMAP plugin that performs regular expression searches and substitutions in received messages.
Please note that this is a relatively simplistic example of how such a plugin could work, and if you try to confuse/break it you will likely succeed.

- [`SMTPBlackHole`](plugins/SMTPBlackHole.py): An example SMTP plugin that accepts incoming email messages but silently discards them without passing to the remote server.
Useful for testing email sending tools with no risk of actually delivering messages.

Expand All @@ -43,4 +50,12 @@ Extend [`BasePlugin`](plugins/BasePlugin.py) to create your own plugins that cus
The two overridable methods `receive_from_client` and `receive_from_server` give access to raw IMAP/POP/SMTP messages/commands as they are received.
The return values from these overridden methods, and the two sender methods `send_to_server` and `send_to_client` allow you to send messages/commands to the client/server (and other chained plugins) in response.
The `log_debug`, `log_info` and `log_error` methods allow you to post messages to the proxy's main log.
Note that plugins are inserted after authentication has finished – you will not receive (or be able to send) anything between the client and/or server until that process is complete.
Note that plugins on the client side are inserted after authentication has finished – you will not receive anything from the client until that process is complete.

### Supporting tools
See the discussion, variables and methods in [`BasePlugin`](plugins/BasePlugin.py) for pointers and suggestions about how to develop your own plugins.
In addition, extending the following examples may help you get started:

- [`/IMAPMessageEditor`](plugins/IMAPMessageEditor.py): An example IMAP plugin helper that can be extended to create other IMAP plugins that modify the content of received messages.
This plugin abstracts away the potentially error-prone message decoding process and instead provides a single method that is called whenever an email is loaded.
See [`IMAPRegexContentReplacer`](plugins/IMAPRegexContentReplacer.py) for an example of this helper in use.

0 comments on commit 6e3c66a

Please sign in to comment.