Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Refused connection" when using versions 2023-03-09 or 2023-05-18 in Windows #179

Closed
bwbug opened this issue Jun 27, 2023 · 18 comments
Closed

Comments

@bwbug
Copy link

bwbug commented Jun 27, 2023

Hello, I'm back, and I'm still unable to run the emailproxy without a console window. As explained in #134, I would like to run the proxy in a way that does make available the systray icon, but does not require a console window. Since #134 was closed, I updated my installation of eamil-oauth2-proxy, and recompiled using the --noconsole option, as follows:

.\pyinstaller --noconsole --onefile emailproxy.py --hidden-import timeago.locales.en

Running the executable no longer causes a crash, and I do see the systray icon but no console window (as desired).

However, when attempting to send email via SMTP, my email client logs the following error:

25908    16: 9.48 Open 127.0.0.1:1587
25908     8: 9.50 Dialog: "Could not connect to "localhost"\r\n"
25908     8: 9.50 Dialog: "\r\n"
25908     8: 9.50 Dialog: "Cause: connection refused (10061)"

Running the proxy in debug mode, the log file only shows the following:

2023-06-26 22:40:46,268: Initialising Email OAuth 2.0 Proxy (version 2023-05-18) from config file C:\Program Installation Files\Email-OAuth2-Proxy_portable\dist\emailproxy.config
2023-06-26 22:40:46,276: Starting POP server at localhost:1995 (unsecured) proxying outlook.office365.com:995 (SSL/TLS)
2023-06-26 22:40:46,291: Starting SMTP server at localhost:1587 (unsecured) proxying smtp.office365.com:587 (STARTTLS)
2023-06-26 22:40:46,291: Initialised Email OAuth 2.0 Proxy - listening for authentication requests. Connect your email client to begin
2023-06-26 22:41:34,735: Stopping Email OAuth 2.0 Proxy

I have checked that an previously compiled executable (which does have a console window) still runs properly and allows the email client to connect to port 1587 for sending by SMTP.

Please advise.

@simonrob
Copy link
Owner

You've imported timeago.locales.en rather than timeago.locales.en_short, which could be the reason?

Also, you're building an essentially identical version to the official release – it might be worth just using that?

@bwbug
Copy link
Author

bwbug commented Jun 27, 2023

I had seen the pre-compiled releases for Windows, but I assumed it wasn't using the --noconsole option, which is why I built my own executable.

Unfortunately, using the official release results in the same behavior ("connection refused"), as does my own build after switching the imported file to timeago.locales.en_short.

I also tried re-building this without the --noconsole option, and still get the same error. (Thus, I should probably change the title of this Issue).

@bwbug bwbug changed the title Compiling with --noconsole option causes refused connection "Refused connection" when using versions 2023-03-09 or 2023-05-18 in Windows Jun 27, 2023
@bwbug
Copy link
Author

bwbug commented Jun 27, 2023

I've tested version 2022-12-14 (which works), version 2023-02-08 (which works), version 2023-03-09 (which does not work), and version 2023-05-18 (which does not work). Thus I've modified the topic title accordingly.

The March 9 and May 18 versions both result in a "Connection Refused" error. This occurs whether I have built the executable myself using PyInstaller or not (i.e., using the pre-built Windows binary). Even running pythonw emailproxy.py does not work.

Furthermore, I should clarify that the error message thrown by the email client ("Could not connect to "localhost". Cause: connection refused (10061)") is the same error message that occurs when the emailproxy.exe is not running at all.


Another issue (which is probably unrelated, but I mention it for completeness) was found in version 2023-03-09 only: When selecting "Quit Email OAuth 2.0 Proxy" from the systray icon menu, the app is not closed (nothing happens). This problems seems to occur only with the pre-compiled release for Windows, not when building my own executable from the .py file.

@bwbug
Copy link
Author

bwbug commented Jun 28, 2023

Since this is some sort of connection issue, tried replacing localhost by ::1 in my email client, but this results in the following error (possibly because the email client may not support IPv6):

Resolving address for "::1"
Error getting network address for "::1"
Cause: host not found (11001)

Using 127.0.0.1 in place of localhost also does not work.


Additional testing:

In a CMD shell, I typed telnet localhost 1587 (to test the SMTP connection), which returned the following string:

220 MN2PR10CA0019.outlook.office365.com Microsoft ESMTP MAIL Service ready at Wed, 28 Jun 2023 02:07:34 +0000

I was then able to connect to the proxy (triggering a prompt to authenticate), as follows:

EHLO localhost
250-BL1PR13CA0260.outlook.office365.com Hello [72.94.160.40]
250-SIZE 157286400
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-AUTH PLAIN LOGIN
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250 SMTPUTF8
AUTH LOGIN
334 VXNlcm5hbWU6
bXl1c2VybmFtZUBteWRvbWFpbi5jb20=
334 UGFzc3dvcmQ6
ZHVtbXlwYXNzd29yZA==

So, at this point, I don't understand why my email client is unable to even establish a connection (especially since it works fine in versions of emailproxy prior to 2023-03-09).

@simonrob
Copy link
Owner

Thanks for following up with this extra detail. The changes since this version have been minor, and there is nothing to do with connection setup, so I have to assume this is something to do with PyInstaller or another dependency. So, please can you just clarify this bit:

Even running pythonw emailproxy.py does not work.

To be extra clear, is it the case that the versions in question (2023-03-09 onwards) do not work even when PyInstaller is not involved at all and you are just downloading and running the script normally? That is very odd, given that telnet connections work.

Please could you provide details about the client you are using, and also the output of python -m pip list.

@mtlg
Copy link

mtlg commented Jun 28, 2023

I believe I have the same problem. Up to 2023-02-08 everything is fine, starting with 2023-03-09 I get connection errors.

I have boiled it down to socket_family=socket.AF_UNSPEC vs. socket_family=socket.AF_INET:

--- email-oauth2-proxy-2023-05-18/emailproxy.py      2023-05-18 21:59:31.000000000 +0200
+++ emailproxy.py       2023-06-28 12:55:56.167192118 +0200
@@ -1513,7 +1513,7 @@
         self.create_socket()
         self.connect(self.server_address)
 
-    def create_socket(self, socket_family=socket.AF_UNSPEC, socket_type=socket.SOCK_STREAM):
+    def create_socket(self, socket_family=socket.AF_INET, socket_type=socket.SOCK_STREAM):
         # connect to whichever resolved IPv4 or IPv6 address is returned first by the system
         for a in socket.getaddrinfo(self.server_address[0], self.server_address[1], socket_family, socket.SOCK_STREAM):
             super().create_socket(a[0], socket.SOCK_STREAM)
@@ -1922,7 +1922,7 @@
         self.bind(self.local_address)
         self.listen(5)
 
-    def create_socket(self, socket_family=socket.AF_UNSPEC, socket_type=socket.SOCK_STREAM):
+    def create_socket(self, socket_family=socket.AF_INET, socket_type=socket.SOCK_STREAM):
         # listen using both IPv4 and IPv6 where possible (python 3.8 and later)
         socket_family = socket.AF_INET6 if socket_family == socket.AF_UNSPEC else socket_family
         if socket_family != socket.AF_INET:

I use the proxy for:

  • Sending (Gmail or O365) with mutt, which works fine with socket_family=socket.AF_UNSPEC only if I replace localhost (mapped to 127.0.0.1) with localhost6 (mapped to ::1).
  • Receiving (IMAP) with fetchmail, same behavior as mutt (error when configured with localhost, fine when configured with localhost6).

Regardless, I still do not see why setting socket_family=socket.AF_UNSPEC would require the use of IPv6 addressing.

@simonrob
Copy link
Owner

Thanks for this – I misunderstood the previous update, so yes, the changes since 2022-02-08 do indeed include modifications to the connection setup. The new default behaviour after this is to try IPv6 first. But (at least in my own testing), the intent is that a failure to set up the IPv6 socket would fall back to IPv4. Clearly on Windows this isn't always happening.

I don't have access to a Windows environment to check myself right now, but please could you confirm:

  • Are both of the changes in your diff required, or just the second? (the first relates to outgoing connections rather than the local host)
  • With the affected proxy versions, are you able to connect if you set each server's local_address explicitly in the proxy's configuration file? It would be useful to know about all three scenarios here:
    • IPv4: local_address = 127.0.0.1
    • IPv6: local_address = ::1
    • Dual-stack: local_address = ::
  • The mutt behaviour is expected in situations where localhost resolves to IPv6, but the fetchmail behaviour is odd. Is it using some sort of custom name resolution, or assuming localhost is always 127.0.0.1?

One potential resolution here is to change the proxy's default local_address to ::, but I'm very cautious about adverse effects (for example, on systems without dual-stack support, or those supporting IPv4 only).

It would be useful to hear from both of you @bwbug and @mtlg about whether adding local_address = :: for these servers resolves things for the proxy versions and clients concerned.

@bwbug
Copy link
Author

bwbug commented Jun 28, 2023

It would be useful to hear from both of you @bwbug and @mtlg about whether adding local_address = :: for these servers resolves things for the proxy versions and clients concerned.

I'm afraid I will need explicit instructions about where in the emailproxy.config file to add the local_address = :: line. Please advise. Update: Nevermind, I found the instructions. I have posted my test results in a separate comment below.

To be extra clear, is it the case that the versions in question (2023-03-09 onwards) do not work even when PyInstaller is not involved at all and you are just downloading and running the script normally?

Yes, I've tested this with both version 2023-03-09 and 2023-05-18 — executing pythonw emailproxy.py brings up the systray icon, but the email client is unable to connect.

Please could you provide details about the client you are using, and also the output of python -m pip list.

The client I'm using is Qualcomm Eudora 7.1.0.9 (released in 2006, thus pre-dating the adoption of IPv6).

Output of py -m pip list:

Package                   Version
------------------------- ---------
altgraph                  0.17.3
bottle                    0.12.23
cffi                      1.15.1
clr-loader                0.2.5
cryptography              39.0.0
future                    0.18.3
pefile                    2022.5.30
Pillow                    9.4.0
pip                       23.1.2
prompt-toolkit            3.0.36
proxy-tools               0.1.0
pycparser                 2.21
pyinstaller               5.13.0
pyinstaller-hooks-contrib 2022.15
pystray                   0.19.4
pythonnet                 3.0.1
pywebview                 4.2.2
pywin32-ctypes            0.2.1
setuptools                65.5.0
six                       1.16.0
timeago                   1.0.16
typing_extensions         4.6.3
wcwidth                   0.2.6

@bwbug
Copy link
Author

bwbug commented Jun 28, 2023

It would be useful to hear from both of you @bwbug and @mtlg about whether adding local_address = :: for these servers resolves things for the proxy versions and clients concerned.

I am please to report that after adding local_address = :: to the [SMTP-1587] section of the emailproxy.config file, my Eudora client is now able to connect to the proxy. I tested this with the 2023-05-18 version, and confirmed that it works either running the pre-compiled binary release for Windows, or by executing pythonw emailproxy.py.

One unexpected behavior was that after making the change to the .config file, Windows Defender Firewall requested that I approve permissions for pythonw.exe or emailconfig.exe (depending on which method I was using to run the proxy). Approving authorizes inbound access to all local and remote ports by TCP and UDP. I imagine that this could create somewhat of a security risk, so I would appreciate if you could clarify the minimum requirements for inbound traffic through the firewall.

By the way, I did test whether the changes to the Firewall settings were responsible for fixing the original connection problem, but this does not appear to be the case. I left the new Firewall rules in place, but reverted the emailproxy.config file (removing the references to local_address = ::); in this case, the email client again was refused a connection to the proxy server.

@mtlg
Copy link

mtlg commented Jun 28, 2023

  1. IPv4: local_address = 127.0.0.1
  • Works if clients point to localhost (i.e., 127.0.0.1)
  • Does not work if clients point to localhost6 (i.e., ::1)
  1. IPv6: local_address = ::1
  • Does not work if clients point to localhost (i.e., 127.0.0.1)
  • Works if clients point to localhost6 (i.e., ::1)
  1. Dual-stack: local_address = ::
  • Works if clients point to localhost (i.e., 127.0.0.1)
  • Works if clients point to localhost6 (i.e., ::1)

Looks coherent, but I'm not sure it was intentional to require users to add a local_address = :: setting for all servers (probably should be the new default) :-)

Regarding which of the two diffs has effect, it's the second, on line 1925:

  • Removed local_address from all servers
  • Set AF_INET on line 1925
    • Clients pointed to localhost work
    • Clients pointed to localhost6 do not work
  • Set AF_UNSPEC on line 1925
    • Clients pointed to localhost do not work
    • Clients pointed to localhost6 work

In the tests above I left AF_UNSPEC on line 1516 (it has no effect anyway).

BTW, I do all the testing on Fedora 38 installed on the real HW (not VM, containers, ...).

@simonrob
Copy link
Owner

Thank you both for following up – this is really helpful.

It does seem like switching the proxy's default local_address value to :: would resolve this, and also in most cases avoid the need to investigate other issues that have been reported for related reasons (e.g., #152, #162, #178).

I will test this in various scenarios, and assuming all goes well, plan to integrate this change in the next release.

@bwbug
Copy link
Author

bwbug commented Jun 30, 2023

@simonrob

I would appreciate if you could address my query above about the requirement to open the firewall:

Approving authorizes inbound access to all local and remote ports by TCP and UDP. I imagine that this could create somewhat of a security risk, so I would appreciate if you could clarify the minimum requirements for inbound traffic through the firewall.

@simonrob
Copy link
Owner

I'm not familiar with the Windows firewall, but assuming it is running on the same host as your client, there is no reason to open any remote ports. If the firewall blocks local connections, then you'd only need to allow the ports it is actively using (i.e., those listed in the configuration file).

@bwbug
Copy link
Author

bwbug commented Jun 30, 2023

@simonrob Does it use UDP or TCP or both?

@simonrob
Copy link
Owner

simonrob commented Jul 1, 2023

IMAP, POP and SMTP all use TCP.

@bwbug
Copy link
Author

bwbug commented Jul 2, 2023

Thank you for the guidance. So I customized the inbound rule (on the Windows Defender Firewall running on the same computer as my email client & emailproxy,exe) so that it only allowed TCP connections to local port 1587 from remote ports 1587, with the scope restricted to local IP address of 127.0.0.1 and a remote IP address of 127.0.0.1. I confirmed that my email client could still send email via the proxy, so that's good (I wasn't sure if the IP addresses would have to be specified as IPv6 or not).

However, then I disabled this firewall rule for testing purposes, and found (to my surprise) that I could still send email using the proxy!? Any insights? Also, I don't recall previously being prompted by the firewall to allow access for the proxy (when I was testing versions earlier than 2023-03-09) — this only happened after I was able to get 2023-03-09/2023-05-18 working by adding the local_address = :: line to the configuration.

@simonrob
Copy link
Owner

simonrob commented Jul 2, 2023

I can't really offer any firewall advice, but remember that the proxy's own ports are all for local connections, and its only external connections are to the actual IMAP/POP/SMTP servers you are using. You may not need any special rules here.

@bwbug
Copy link
Author

bwbug commented Jul 2, 2023

I understand, I was just confused why the emailproxy seems to be inconsistent as to when it triggers involvement of the firewall.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants