openldap-tls-no-reuse-of-tls_session.patch 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. TLS: do not reuse tls_session if hostname check fails
  2. If multiple servers are specified, the connection to the first one succeeds, and the hostname verification fails,
  3. *tls_session is not dropped, but reused when connecting to the second server.
  4. This is a problem with Mozilla NSS backend because another handshake cannot be performed on the same file descriptor.
  5. From this reason, hostname checking was moved into ldap_int_tls_connect() before connection error handling.
  6. Author: Jan Vcelak <jvcelak@redhat.com>
  7. Upstream ITS: #7373
  8. Resolves: #852476
  9. diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
  10. index 10b993b..a3cd590 100644
  11. --- a/libraries/libldap/tls2.c
  12. +++ b/libraries/libldap/tls2.c
  13. @@ -320,7 +320,7 @@ update_flags( Sockbuf *sb, tls_session * ssl, int rc )
  14. */
  15. static int
  16. -ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
  17. +ldap_int_tls_connect( LDAP *ld, LDAPConn *conn, const char *host )
  18. {
  19. Sockbuf *sb = conn->lconn_sb;
  20. int err;
  21. @@ -365,6 +365,10 @@ ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
  22. errno = WSAGetLastError();
  23. #endif
  24. + if ( err == 0 ) {
  25. + err = ldap_pvt_tls_check_hostname( ld, ssl, host );
  26. + }
  27. +
  28. if ( err < 0 )
  29. {
  30. char buf[256], *msg;
  31. @@ -495,7 +499,15 @@ ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
  32. {
  33. tls_session *session = s;
  34. - return tls_imp->ti_session_chkhost( ld, session, name_in );
  35. + if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER &&
  36. + ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW) {
  37. + ld->ld_errno = tls_imp->ti_session_chkhost( ld, session, name_in );
  38. + if (ld->ld_errno != LDAP_SUCCESS) {
  39. + return ld->ld_errno;
  40. + }
  41. + }
  42. +
  43. + return LDAP_SUCCESS;
  44. }
  45. int
  46. @@ -857,7 +869,7 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
  47. #endif /* LDAP_USE_NON_BLOCKING_TLS */
  48. ld->ld_errno = LDAP_SUCCESS;
  49. - ret = ldap_int_tls_connect( ld, conn );
  50. + ret = ldap_int_tls_connect( ld, conn, host );
  51. #ifdef LDAP_USE_NON_BLOCKING_TLS
  52. while ( ret > 0 ) { /* this should only happen for non-blocking io */
  53. @@ -878,7 +890,7 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
  54. } else {
  55. /* ldap_int_poll called ldap_pvt_ndelay_off */
  56. ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_SET_NONBLOCK, sb );
  57. - ret = ldap_int_tls_connect( ld, conn );
  58. + ret = ldap_int_tls_connect( ld, conn, host );
  59. if ( ret > 0 ) { /* need to call tls_connect once more */
  60. struct timeval curr_time_tv, delta_tv;
  61. @@ -935,20 +947,6 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
  62. return (ld->ld_errno);
  63. }
  64. - ssl = ldap_pvt_tls_sb_ctx( sb );
  65. - assert( ssl != NULL );
  66. -
  67. - /*
  68. - * compare host with name(s) in certificate
  69. - */
  70. - if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER &&
  71. - ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW) {
  72. - ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host );
  73. - if (ld->ld_errno != LDAP_SUCCESS) {
  74. - return ld->ld_errno;
  75. - }
  76. - }
  77. -
  78. return LDAP_SUCCESS;
  79. }