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

Add Host HTTP header to MS-KKDCP requests #507

Closed
wants to merge 1 commit into from

Conversation

tiran
Copy link
Contributor

@tiran tiran commented Aug 8, 2016

Some webservers require a Host HTTP header for TLS connections with
SNI (server name indicator). For example Apache HTTPD with a recent
version of mod_nss aborts HTTPS requests without Host header with
response '400 Bad Request' and error message:

Hostname example.org provided via SNI, but no hostname provided in
HTTP request

The HTTP Host header is also required for virtual hosts. TLS SNI support
was added in 4b6045a.

https://bugzilla.redhat.com/show_bug.cgi?id=1364993

Signed-off-by: Christian Heimes cheimes@redhat.com

@greghudson
Copy link
Member

In resolve_server(), portbuf is a local array variable. You appear to be storing an alias to this array in the resulting struct conn_state, which is then used after resolve_server() exits. I believe that's a memory error. Can you confirm that with valgrind and fix it?

@tiran
Copy link
Contributor Author

tiran commented Aug 8, 2016

Ah, you are right. I have addressed the issue in my latest patch. portbuf is now 6 chars wide, enough to store the decimal representation of UINT16_MAX. The local portbuf buffer is strncpy()ed to conn_state.http.port[6] char array. The overflow check after snprintf() ensures that neither portbuf nor http.port can overflow.

@@ -700,6 +703,8 @@ add_connection(struct conn_state **conns, k5_transport transport,
state->service_read = service_https_read;
state->http.uri_path = uri_path;
state->http.servername = hostname;
strncpy(state->http.port, port, sizeof(state->http.port)-1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If port is NULL this will crash.

@tiran
Copy link
Contributor Author

tiran commented Aug 9, 2016

I tracked servername all the way down into the TLS layer. The k5tls plugin assume that servername is never NULL. add_connection() does not verify that servername != NULL for HTTPS transport. What do you think about a check in add_connection()

     } else if (transport == HTTPS) {
+        if (hostname == NULL || port == NULL)
+            return EINVAL;

@greghudson
Copy link
Member

Modules can't add HTTPS entries, so that should be okay. However, please use strlcpy(), not strncpy().

@greghudson
Copy link
Member

I would add an assertion, not a check-and-return-EINVAL, unless you think there's a way to produce that condition using configuration. Adding a check also seems out of scope for this PR.

Some webservers require a Host HTTP header for TLS connections with
SNI (server name indicator). For example Apache HTTPD with a recent
version of mod_nss aborts HTTPS requests without Host header with
response '400 Bad Request' and error message:

    Hostname example.org provided via SNI, but no hostname provided in
    HTTP request

The HTTP Host header is also required for virtual hosts. TLS SNI support
was added in 4b6045a.

https://bugzilla.redhat.com/show_bug.cgi?id=1364993

Signed-off-by: Christian Heimes <cheimes@redhat.com>
@tiran
Copy link
Contributor Author

tiran commented Aug 9, 2016

Thanks for your feedback. I have added an assert() and replaced strncpy() with strlcpy(). I didn't know about strlcpy() before. This function from FreeBSD is much nicer to use than strncpy().

@frozencemetery
Copy link
Contributor

Not sure why Travis is upset; this passes for me locally.

@tlyu
Copy link
Member

tlyu commented Aug 9, 2016

I restarted the build. There was a known outage with the Travis infrastructure.

@tiran
Copy link
Contributor Author

tiran commented Aug 10, 2016

For reference here is what happens with KRB5 >= 1.14 on the client:

$ KRB5_TRACE=/dev/stdout KRB5_CONFIG=inventory/krb5_kkdcp.conf kinit admin
[16579] 1470842151.257231: Getting initial credentials for admin@IPA.EXAMPLE
[16579] 1470842151.257407: Sending request (164 bytes) to IPA.EXAMPLE
[16579] 1470842151.272315: Resolving hostname master.ipa.example
[16579] 1470842151.281542: TLS certificate name matched "master.ipa.example"
[16579] 1470842151.283323: Sending HTTPS request to https 192.168.121.83:443
[16579] 1470842151.283511: HTTPS error: HTTP/1.1 400 Bad Request\x0d\x0aDate: Wed, 10 Aug 2016 15:15:51 GMT\x0d\x0aServer: Apache/2.4.23 (Fedora) mod_auth_gssapi/1.4.0 mod_nss/1.0.12 NSS/3.23 Basic ECC mod_wsgi/4.4.8 Python/2.7.12\x0d\x0aContent-Length: 226\x0d\x0aConnection: close\x0d\x0aContent-Type: text/html; charset=iso-8859-1\x0d\x0a\x0d\x0a<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">\x0a<html><head>\x0a<title>400 Bad Request</title>\x0a</head><body>\x0a<h1>Bad Request</h1>\x0a<p>Your browser sent a request that this server could not understand.<br />\x0a</p>\x0a</body></html>\x0a
[16579] 1470842151.283541: Terminating TCP connection to https 192.168.121.83:443
kinit: Cannot contact any KDC for realm 'IPA.EXAMPLE' while getting initial credentials

Apache HTTP error log:

[Wed Aug 10 15:15:51.308259 2016] [:error] [pid 32627] Hostname master.ipa.example provided via SNI, but no hostname provided in HTTP request

With a patched build of krb5-libs and krb5-workstation (http://koji.fedoraproject.org/koji/taskinfo?taskID=15189061), MS-KKDCP works again.

$ KRB5_TRACE=/dev/stdout KRB5_CONFIG=inventory/krb5_kkdcp.conf kinit admin
[16987] 1470842198.713707: Getting initial credentials for admin@IPA.EXAMPLE
[16987] 1470842198.713837: Sending request (164 bytes) to IPA.EXAMPLE
[16987] 1470842198.713953: Resolving hostname master.ipa.example
[16987] 1470842198.722624: TLS certificate name matched "master.ipa.example"
[16987] 1470842198.724380: Sending HTTPS request to https 192.168.121.83:443
[16987] 1470842198.728973: Received answer (252 bytes) from https 192.168.121.83:443
[16987] 1470842198.728982: Terminating TCP connection to https 192.168.121.83:443
[16987] 1470842198.729064: Response was from master KDC
[16987] 1470842198.729084: Received error from KDC: -1765328359/Additional pre-authentication required
[16987] 1470842198.729112: Processing preauth types: 136, 19, 2, 133
[16987] 1470842198.729120: Selected etype info: etype aes256-cts, salt "e{HpJ%/!BH>=`|a>", params ""
[16987] 1470842198.729125: Received cookie: MIT
Password for admin@IPA.EXAMPLE: 
[16987] 1470842203.740547: AS key obtained for encrypted timestamp: aes256-cts/D1AE
[16987] 1470842203.740582: Encrypted timestamp (for 1470842203.764815): plain 301AA011180F32303136303831303135313634335AA10502030BAB8F, encrypted AAD295DA168C49ABD619ED0977F2E36381BEC9BABD33EC858033802DE92B2E552DDFEC15462489F92E4FA965651A5A1002E599CA70C0D2DD
[16987] 1470842203.740598: Preauth module encrypted_timestamp (2) (real) returned: 0/Success
[16987] 1470842203.740602: Produced preauth for next request: 133, 2
[16987] 1470842203.740619: Sending request (257 bytes) to IPA.EXAMPLE
[16987] 1470842203.740651: Resolving hostname master.ipa.example
[16987] 1470842203.747881: TLS certificate name matched "master.ipa.example"
[16987] 1470842203.749562: Sending HTTPS request to https 192.168.121.83:443
[16987] 1470842203.796191: Received answer (724 bytes) from https 192.168.121.83:443
[16987] 1470842203.796207: Terminating TCP connection to https 192.168.121.83:443
[16987] 1470842203.796341: Response was from master KDC
[16987] 1470842203.796367: Processing preauth types: 19
[16987] 1470842203.796377: Selected etype info: etype aes256-cts, salt "e{HpJ%/!BH>=`|a>", params ""
[16987] 1470842203.796384: Produced preauth for next request: (empty)
[16987] 1470842203.796393: AS key determined by preauth: aes256-cts/D1AE
[16987] 1470842203.796433: Decrypted AS reply; session key is: aes256-cts/08B6
[16987] 1470842203.796448: FAST negotiation: available
[16987] 1470842203.796464: Initializing ...

@greghudson
Copy link
Member

Pushed to master as 69c8662.

@greghudson greghudson closed this Aug 10, 2016
@tiran
Copy link
Contributor Author

tiran commented Aug 10, 2016

@greghudson please push the fix to 1.14, too.

@greghudson
Copy link
Member

I marked it for backport when I pushed to commit. Tom will be doing the cherry-pick onto the 1.14 branch when he next does release engineering work.

@tiran
Copy link
Contributor Author

tiran commented Aug 10, 2016

@greghudson thank you! @frozencemetery explained to me how you are dealing with backports.

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