cyrusimap / cyrus-imapd

Cyrus IMAP is an email, contacts and calendar server
http://cyrusimap.org
Other
531 stars 146 forks source link

When redirecting /.well-known/jmap it redirects from https to plain text http #3604

Open mildred opened 3 years ago

mildred commented 3 years ago

I have a server with a cyrus listening on HTTP on localhost port 8080 with a reverse proxy doing the TLS termination.

To ensure that Cyrus understands the connection is secure, the cyrus.conf line for this service contains -p 2:

    httpss      cmd="httpd -C /etc/cyrus/imapd.conf -p 2 -U 30" listen="localhost:8080" prefork=0 maxchild=100

Now, when I make a request to https://hostname/.well-known/jmap I get redirected with Location: http://hostname/.well-known/jmap. I believe the problem is with this code:

https://github.com/cyrusimap/cyrus-imapd/blob/463507c667052ea80e088c05b10ce91a7dbd5534/imap/httpd.c#L1624

It redirects with https only if the https variable is true, which happens only if Cyrus itself is doing the TLS part. It should check also the variable extprops_ssf to ensure that an external reverse proxy that does https will count as well.

I suggest the following change:

                 buf_printf(&txn->buf, "%s://%s",
-                           https ? "https" : "http", hdr[0]);
+                           (https || extprops_ssf > 1) ? "https" : "http", hdr[0]);

Or provide a new CLI flag to tell specifically that we are using the https protocol.

dilyanpalauzov commented 3 years ago

-p 2 could mean SASL Security Layer, which is not TLS, like GSSAPI Security Layer.

You are entitled to configure the front-end server to do the rewritings. With nginx this done with the proxy_redirect directive.

I personally add by the front-end server a Forwarded header: proxy_set_header Forwarded "proto=https;host=example.org"; and within httpd evaluate the proto= part. This results correct results, e.g. when it comes to /freebusy/user/zzz answers.