-
Notifications
You must be signed in to change notification settings - Fork 253
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
fix segfault in ngx_http_auth_ldap_ssl_handshake_handler and add "chain" option for ssl_check_cert #237
base: master
Are you sure you want to change the base?
Conversation
This reverts commit bf64cf2, reversing changes made to f022103. This change isn't right -- it an LDAP setup when `group_attribute_is_dn on` is enabled, which is what this section of code (kvspb@bf64cf2#diff-c05c0daefb48996cbf510b81002b49bcR2230) is conditionally targeting. This original PR kvspb#199 changed the underlying LDAP query (eg `user_val`) from looking up the user's DN as a group attribute in LDAP (eg set via the `group_attribute` directive in nginx) to looking up the _group's_ DN, which isn't right and won't work. This PR reverts the previous change to make this work correctly again. Fwiw, the originally-referenced issue kvspb#180 seems to be a completely different issue, relating to escaping and parentheses.
…on) or chain (verify cert chain but not hostname/IP)
…l_handshake_handler with ssl_check_cert and ssl_ca_dir
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've outlined all of the code changes for the PR, let me know if you have any concerns or questions.
@@ -26,6 +26,7 @@ | |||
* SUCH DAMAGE. | |||
*/ | |||
|
|||
#include <sys/socket.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added sys/socket.h
for AF_INET
and AF_INET6
later in ngx_http_auth_ldap_ssl_handshake_handler
#define SSL_CERT_VERIFY_OFF 0 | ||
#define SSL_CERT_VERIFY_FULL 1 | ||
#define SSL_CERT_VERIFY_CHAIN 2 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These constants are used as possible values for ngx_http_auth_ldap_server_t.ssl_check_cert
to indicate off
, on
/full
and chain
verification as described in the PR body.
"http_auth_ldap: 'ssl_cert_check': cannot verify remote certificate's domain name because " | ||
"your version of OpenSSL is too old. " | ||
"Please install OpenSSL >= 1.0.2 and recompile nginx."); | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leave directives for checking OPENSSL_VERSION_NUMBER
in place. If ssl_check_cert
is specified, on
and full
indicate full certificate checking (chain and host/IP), chain
indicates checking certificate chain only but not host/IP, and anything else means off
(don't verify the certificate).
else { // very unlikely indeed | ||
ngx_http_auth_ldap_close_connection(c); | ||
return; | ||
if (c->server->ssl_check_cert == SSL_CERT_VERIFY_CHAIN) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handle chain
(SSL_CERT_VERIFY_CHAIN
) case: we've already called SSL_get_verify_result
and got chain_verified
assigned, which will be checked below. Set addr_verified
to 1
(success) so it will get ignored in the checks later. Don't call X509_check_host
or X509_check_ip
.
if (!addr_verified) { // domain not in cert? try IP | ||
size_t len; // get IP length | ||
|
||
struct sockaddr *conn_sockaddr = NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This next few lines of code was what was causing the segfault in kvspb/nginx-auth-ldap/#236. conn->sockaddr
was always NULL
for me. So check a few places that (I think) should have the value we need and use one of them, if set. If there's anywhere my logic might be wrong, it would be here, in assuming the values of these sockaddr
structs represent the same thing. But I think it's right.
|
||
if (conn_sockaddr->sa_family == AF_INET) len = 4; | ||
else if (conn_sockaddr->sa_family == AF_INET6) len = 16; | ||
else { // very unlikely indeed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are now checking AF_INET
and AF_INET6
rather than just 4
and 6
, which wouldn't have ever been correct anyway.
ngx_http_auth_ldap_close_connection(c); | ||
return; | ||
} | ||
addr_verified = X509_check_ip(cert, (const unsigned char*)conn_sockaddr->sa_data, len, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the comment above where I assign conn_sockaddr
update counter (this is always reset in | ||
ngx_http_auth_ldap_connect() for a successful ldap | ||
connection | ||
c->server->max_down_retries_count < c->server->max_down_retries) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just my editor stripping trailing spaces
@@ -1542,7 +1566,7 @@ ngx_http_auth_ldap_read_handler(ngx_event_t *rev) | |||
// timer call to this read handler again | |||
ngx_http_auth_ldap_reconnect_handler(rev); | |||
return; | |||
} | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just my editor stripping trailing spaces
This patches in kvspb/nginx-auth-ldap#237 to handle segfaults produced by failure to make SSL connections to LDAP servers.
ping... project still active? |
PR: kvspb#237 from mmguero-dev
This pull request addresses two things relating to
ngx_http_auth_ldap_ssl_handshake_handler
:conn->sockaddr
is non-NULL. Instead, it tries to get it fromconn->sockaddr
,c->conn.sockaddr
, and finallyc->server->parsed_url.sockaddr.sockaddr
, in that order:Additionally, it uses the correct
AF_INET
andAF_INET6
constants for checkingsa_family
for IPv4 vs. IPv6, rather than the incorrect4
and6
integer literals.ssl_check_cert
now acceptschain
in addition toon
andoff
:on
- full certificate verification inngx_http_auth_ldap_ssl_handshake_handler
, meaning checking the certificate chain withSSL_get_verify_result
andX509_check_host
orX509_check_ip
(same as previouson
behavior;full
can also be used to mean the same thing ason
)off
- no certificate verification (same as previousoff
behavior)chain
- perform certificate chain verification withSSL_get_verify_result
, but don't do host/IP verification (i.e., don't callX509_check_host
orX509_check_ip
)This should not break backwards compatibility. I've been testing it in conjunction with an issue in my project (idaholab/Malcolm#128) and it addresses my needs. I've left the checks in place for
OPENSSL_VERSION_NUMBER
to leave the warnings in place if compiled with too old a version of openssl.Let me know if you've got any issues or questions.