Bug #74636 [Asn]: [krb5] negotiate auth broken for vhosts because of hostname canonicalization
| From: | chanlists at googlemail dot com | Date: | Tue, 23 May 2017 22:32:29 +0000 |
| Subject: | Bug #74636 [Asn]: [krb5] negotiate auth broken for vhosts because of hostname canonicalization | ||
| References: | 1 | Groups: | php.pecl.dev |
| Request: | Send a blank email to pecl-dev+get-14640@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=74636&edit=1
ID: 74636
User updated by: chanlists at googlemail dot com
Reported by: chanlists at googlemail dot com
Summary: [krb5] negotiate auth broken for vhosts because of
hostname canonicalization
Status: Assigned
Type: Bug
Package: PECL
Operating System: debian 8
PHP Version: 5.6.30
Assigned To: mbechler
Block user comment: N
Private report: N
New Comment:
I can confirm that previously dns canonicalization had to be turned off. With your new code, if I
specify the service principle as an argument to the constructor, it works regardless of the
dns_canonicalize_hostname setting in /etc/krb5.conf. This seems to resolve the issues I raised.
Thanks a lot for fixing it! Cheers,
Christian
Previous Comments:
------------------------------------------------------------------------
[2017-05-23 11:28:33] mbechler at eenterphace dot org
Regarding the canonicalization, really looks like GSS_C_NT_HOSTBASED_SERVICE name types may be
canonicalized.
Can you verify that it is fixed by using GSS_KRB5_NT_PRINCIPAL_NAME and passing "HTTP/%s"
instead. Downside might be that domain->realm is probably not applied (therefor always uses the
default realm), so I would probably leave it as is for the "magic" case.
Just commited a change adding the argument and parsing the name in that case with
GSS_KRB5_NT_PRINCIPAL_NAME, that way the default would be the best guess we are able to make while
allowing total control when overriding it.
------------------------------------------------------------------------
[2017-05-23 10:03:35] mbechler at eenterphace dot org
Absolutely right, that is missing and I had noticed that before and even thought that I had added it
- but that does not seem to be the case.
Adding a constructor argument to KRB5NegotiateAuth for overriding the SPN sounds good? I think that
would be the most obvious choice.
Do you really need to disable "dns_canonicalize_hostname" (except for the client if it is
run on the same host)? It would really surprise me if the library did perform hostname
canonicalization on the server name for acceptor credentials.
If you provide a patch, I'll be happy to merge that.
------------------------------------------------------------------------
[2017-05-23 09:38:38] chanlists at googlemail dot com
I would actually prefer to be able to set the service principle using a method that changes a
property, and use the current behavior as the default method....
------------------------------------------------------------------------
[2017-05-23 09:29:22] requinix@php.net
This sounds like something that should be controlled by an INI setting.
------------------------------------------------------------------------
[2017-05-23 09:09:04] chanlists at googlemail dot com
Description:
------------
Suppose we are using a virtual host in apache where the name of the virtual host name <vhost>
is a cname for the actual hostname <hostname>. In this case, the web browser will present a
service ticket for HTTP/<vhost>, but the krb5 package will set the service principal to
HTTP/<hostname> because of the use of gethostbyname() in the KRB5NegotiateAuth constructor.
This will not work. If I modify the constructor as follows, it works:
server_name = zend_compat_hash_find(HASH_OF(server), "SERVER_NAME",
sizeof("SERVER_NAME"));
if ( server_name != NULL ) {
char *hostname = Z_STRVAL_P(server_name);
// struct hostent* host = gethostbyname(hostname);
// if(!host) {
// zend_throw_exception(NULL, "Failed to get server FQDN - Lookup
failure", 0 TSRMLS_CC);
// return;
//}
nametmp.length = strlen(hostname) + 6;
nametmp.value = emalloc(sizeof(char)*nametmp.length);
snprintf(nametmp.value, nametmp.length, "HTTP@%s",hostname);
Note that for this to work, one also has to set
dns_canonicalize_hostname = false
in /etc/krb5.conf because otherwise the krb5 library will try to do hostname canonicalization as
well. So I think there should either be a way to set the name of the service principal using a
method, or hostname canonicalization should be disabled in the krb5 library as above, or it should
be possible to turn it off with a flag. I would be happy to contribute a patch depending on what you
prefer. Thanks for this great piece of software,
Christian
Test script:
---------------
see above
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74636&edit=1