Skip to content

Commit 6f9268c

Browse files
authored
Switch to nonblocking mode for all connections (#58)
A full rewrite and much-improved implementation of local certificate handling, now used for both local and remote connections. Fixes #52.
1 parent 508ae4b commit 6f9268c

File tree

3 files changed

+187
-86
lines changed

3 files changed

+187
-86
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ After your accounts are fully set-up and authorised, no further proxy interactio
3131
### OAuth 2.0 client credentials
3232
As part of the proxy setup process you need to provide an OAuth 2.0 `client_id` and `client_secret` to allow it to authenticate with email servers on your behalf.
3333

34-
If you have an existing client ID and secret for a desktop app, you can use these directly in the proxy. If this is not possible, you can also reuse the client ID and secret from any email client that supports IMAP/POP/SMTP OAuth 2.0 authentication with the email server you would like to connect to (such as the various [open](https://github.com/mozilla/releases-comm-central/blob/master/mailnews/base/src/OAuth2Providers.jsm) [source](https://gitlab.gnome.org/GNOME/evolution-data-server/-/blob/master/CMakeLists.txt) [clients](https://gitlab.gnome.org/GNOME/gnome-online-accounts/-/blob/master/meson_options.txt) with OAuth 2.0 support), but please do this with care and restraint as access through reused tokens will be associated with the token owner rather than your own client.
34+
If you have an existing client ID and secret for a desktop app, you can use these directly in the proxy. If this is not possible, you can also reuse the client ID and secret from any email client that supports IMAP/POP/SMTP OAuth 2.0 authentication with the email server you would like to connect to (such as the [various](https://github.com/mozilla/releases-comm-central/blob/master/mailnews/base/src/OAuth2Providers.jsm) [open](https://github.com/Foundry376/Mailspring/blob/master/app/internal_packages/onboarding/lib/onboarding-constants.ts) [source](https://gitlab.gnome.org/GNOME/evolution-data-server/-/blob/master/CMakeLists.txt) [clients](https://gitlab.gnome.org/GNOME/gnome-online-accounts/-/blob/master/meson_options.txt) with OAuth 2.0 support), but please do this with care and restraint as access through reused tokens will be associated with the token owner rather than your own client.
3535

3636
If you do not have access to credentials for an existing client you will need to register your own. The process to do this is different for each provider, but the registration guides for several common ones are linked below. In all cases, when registering, make sure your client is set up to use an OAuth scope that will give it permission to access IMAP/POP/SMTP – see the sample configuration file for examples.
3737

@@ -70,7 +70,7 @@ On macOS this can be viewed using Console.app or `log stream --predicate 'subsys
7070

7171
Please note that debug mode may also result in your login credentials being printed to the log (though this is avoided where possible). However, it is worth pointing out that because account authorisation is handled entirely through OAuth 2.0 in a web browser, while the username you set in your email client must be correct, the password used for the IMAP/POP/SMTP connection can be anything you like, and does not need to be the one you actually use to log in to your account. The password you provide via your email client is used only to encrypt and decrypt the authentication token that the proxy transparently sends to the server on your behalf. Because of this, if you are concerned about debug mode and security you can use a test password for debugging and then replace it with a secure password (and authenticate again) once set up.
7272

73-
It is often helpful to be able to view the raw connection details when debugging (i.e., without using your email client). This can be achieved using `telnet`, [Putty](https://www.chiark.greenend.org.uk/~sgtatham/putty/) or similar. For example, to test the Office 365 IMAP server from the [example configuration](emailproxy.config), first open a connection using `telnet localhost 1993`, and then send a login command: `a1 login [email protected] password`, replacing `[email protected]` with your email address, and `password` with any value you like during testing (see above for why the password is irrelevant). If you have already authorised your account with the proxy you should see a response starting with `a1 OK`; if not, this command should trigger a notification from the proxy about authorising your account.
73+
It is often helpful to be able to view the raw connection details when debugging (i.e., without using your email client). This can be achieved using `telnet`, [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/) or similar. For example, to test the Office 365 IMAP server from the [example configuration](emailproxy.config), first open a connection using `telnet localhost 1993`, and then send a login command: `a1 login [email protected] password`, replacing `[email protected]` with your email address, and `password` with any value you like during testing (see above for why the password is irrelevant). If you have already authorised your account with the proxy you should see a response starting with `a1 OK`; if not, this command should trigger a notification from the proxy about authorising your account.
7474

7575
### Dependencies and setup
7676
On macOS the setup and installation instructions above should automatically install all required dependencies. Any error messages you may encounter (for example, with your `pip` version and `cryptograpy`, or `pillow` and `imagingft` dependencies, or [macOS SSL failures](https://github.com/simonrob/email-oauth2-proxy/issues/14#issuecomment-1077379254)) normally give clear explanations of the issues and point to instructions for resolving these problems. Please [open an issue](https://github.com/simonrob/email-oauth2-proxy/issues) if you encounter any other problems here.
@@ -81,6 +81,8 @@ A similar issue may occur on Windows with the [pythonnet](https://github.com/pyt
8181

8282
If you are using the proxy in a non-GUI environment it is also possible to skip installation of dependencies that apply only to the interactive version. To do this, install the script's requirements via `python -m pip install -r requirements-no-gui.txt`, and pass the [`--no-gui`](#optional-arguments-and-configuration) argument when starting the proxy. Please note that the proxy was designed as a GUI-based tool from the outset due to the inherently interactive nature of OAuth 2.0 authorisation, and there are limitations to its ability to support fully no-GUI operation. See the [optional arguments and configuration](#optional-arguments-and-configuration) section of this file for further details.
8383

84+
Python 3.6 or later is required to run the proxy. The [python2 branch](https://github.com/simonrob/email-oauth2-proxy/tree/python2) provides minimal compatibility with Python 2.7, but with a limited feature set, and only very occasional maintenance. See [issue 38](https://github.com/simonrob/email-oauth2-proxy/issues/38) for further discussion.
85+
8486
### Known issues
8587
- With some combinations of operating systems, web engines and virtual environments, keyboard control or input to the proxy's popup authorisation window may not always work. On Windows this is normally limited to keyboard shortcuts (i.e., copy/paste), but in some virtual environments on macOS the entire keyboard may not work. As a workaround, the proxy will enable pywebview's debug mode when you run the proxy in debug mode, which should allow you to use the right-click context menu to copy/paste to enter text.
8688
- On more recent macOS versions (10.14 and later), you may find that you need to manually load the proxy's launch agent in order to trigger a file access permission prompt when first running as a service. You will know if intervention is necessary if the proxy exits (rather than restarts) the first time you click `Start at login` from its menu bar icon. To resolve this, exit the proxy and then run `launchctl load ~/Library/LaunchAgents/ac.robinson.email-oauth2-proxy.plist` from a terminal. A permission pop-up should appear requesting file access for python. Once this has been approved, the proxy's menu bar icon will appear as normal. In some cases — particularly when running the proxy in a virtual environment, or using the built-in macOS python, rather than the python.org version, or installations managed by, e.g., homebrew, pyenv, etc — the permission prompt does not appear. If this happens it is worth first trying to `unload` and then `load` the service via `launchctl`. If this still does not cause the prompt to appear, the only currently-known resolution is to run the proxy outside of a virtual environment and manually grant Full Disk Access to your python executable via the privacy settings in the macOS System Preferences. You may also need to edit the proxy's launch agent plist file, which is found at the location given in the command above, to set the path to your python executable – it must be the real path rather than a symlink (the `readlink` command can help here). Fortunately this is a one-time fix, and once the proxy loads successfully via this method you will not need to adjust its startup configuration again (except perhaps when upgrading to a newer major macOS version, in which case just repeat the procedure).

emailproxy.config

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,17 @@ client_secret = *** your client secret here ***
140140

141141
[Advanced proxy configuration]
142142
documentation = The parameters below control advanced options for the proxy. In most cases you will not need to modify
143-
the values in this section. If any of these values are not found, the proxy will assume the default value, which
144-
can be found in the example config file (https://github.com/simonrob/email-oauth2-proxy/blob/main/emailproxy.config)
145-
146-
Parameter documentation:
147-
- delete_account_token_on_password_error (default = True): Once an account has been authenticated via the proxy, if
148-
there is a login attempt with a different (local) password, its default behaviour is to remove the saved OAuth 2.0
149-
credentials and present a new authentication request. This is a sensible default for local use as it means that a
150-
password typo does not give the false impression that the proxy has somehow made the account inaccessible. However,
151-
if the proxy is used in a headless (often also public-facing) context, where authentication flows are more likely to
152-
be laborious or need administrator intervention, this can potentially result in a denial-of-service issue, whether
153-
malicious or not. Set to False and the proxy will instead return an error when an incorrect password is provided.
143+
the values in this section. If any of these values are not found, the proxy will assume the default value, which
144+
can be found in the example config file (https://github.com/simonrob/email-oauth2-proxy/blob/main/emailproxy.config)
145+
146+
Parameter documentation:
147+
- delete_account_token_on_password_error (default = True): Once an account has been authenticated via the proxy, if
148+
there is a login attempt with a different (local) password, its default behaviour is to remove the saved OAuth 2.0
149+
credentials and present a new authentication request. This is a sensible default for local use as it means that a
150+
password typo does not give the false impression that the proxy has somehow made the account inaccessible. However,
151+
if the proxy is used in a headless (often also public-facing) context, where authentication flows are more likely to
152+
be laborious or need administrator intervention, this can potentially result in a denial-of-service issue, whether
153+
malicious or not. Set to False and the proxy will instead return an error when an incorrect password is provided.
154154

155155
[emailproxy]
156156
delete_account_token_on_password_error = False

0 commit comments

Comments
 (0)