@@ -1921,6 +1921,29 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* option
19211921} /* }}} */
19221922
19231923#ifdef MONGOC_ENABLE_SSL
1924+
1925+ static void php_phongo_mongoc_ssl_opts_from_uri (mongoc_ssl_opt_t * ssl_opt , mongoc_uri_t * uri , bool * any_ssl_option_set )
1926+ {
1927+ const char * pem_file = mongoc_uri_get_option_as_utf8 (uri , MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE , NULL );
1928+ const char * pem_pwd = mongoc_uri_get_option_as_utf8 (uri , MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD , NULL );
1929+ const char * ca_file = mongoc_uri_get_option_as_utf8 (uri , MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE , NULL );
1930+
1931+ ssl_opt -> pem_file = pem_file ? estrdup (pem_file ) : NULL ;
1932+ ssl_opt -> pem_pwd = pem_pwd ? estrdup (pem_pwd ) : NULL ;
1933+ ssl_opt -> ca_file = ca_file ? estrdup (ca_file ) : NULL ;
1934+ ssl_opt -> weak_cert_validation = mongoc_uri_get_option_as_bool (uri , MONGOC_URI_SSLALLOWINVALIDCERTIFICATES , false);
1935+ ssl_opt -> allow_invalid_hostname = mongoc_uri_get_option_as_bool (uri , MONGOC_URI_SSLALLOWINVALIDHOSTNAMES , false);
1936+
1937+ /* Boolean options default to false, so we cannot consider them for
1938+ * any_ssl_option_set. This isn't actually a problem as libmongoc will
1939+ * already have assigned them when creating the client, enabling SSL, and
1940+ * assigning SSL options. Therefore, we only need to check for non-defaults
1941+ * (i.e. non-NULL strings, true booleans). */
1942+ if (pem_file || pem_pwd || ca_file || ssl_opt -> weak_cert_validation || ssl_opt -> allow_invalid_hostname ) {
1943+ * any_ssl_option_set = true;
1944+ }
1945+ }
1946+
19241947static inline char * php_phongo_fetch_ssl_opt_string (zval * zoptions , const char * key , int key_len )
19251948{
19261949 int plen ;
@@ -1934,9 +1957,10 @@ static inline char* php_phongo_fetch_ssl_opt_string(zval* zoptions, const char*
19341957 return value ;
19351958}
19361959
1937- static mongoc_ssl_opt_t * php_phongo_make_ssl_opt (zval * zoptions TSRMLS_DC )
1960+ static mongoc_ssl_opt_t * php_phongo_make_ssl_opt (mongoc_uri_t * uri , zval * zoptions TSRMLS_DC )
19381961{
19391962 mongoc_ssl_opt_t * ssl_opt ;
1963+ bool any_ssl_option_set = false;
19401964
19411965 if (!zoptions ) {
19421966 return NULL ;
@@ -1963,44 +1987,76 @@ static mongoc_ssl_opt_t* php_phongo_make_ssl_opt(zval* zoptions TSRMLS_DC)
19631987
19641988 ssl_opt = ecalloc (1 , sizeof (mongoc_ssl_opt_t ));
19651989
1990+ /* If SSL options are set in the URL, we need to read them and set them on
1991+ * the options struct so we can merge potential options from passed in
1992+ * driverOptions (zoptions) */
1993+ if (mongoc_uri_get_ssl (uri )) {
1994+ php_phongo_mongoc_ssl_opts_from_uri (ssl_opt , uri , & any_ssl_option_set );
1995+ }
1996+
19661997 /* Check canonical option names first and fall back to SSL context options
19671998 * for backwards compatibility. */
19681999 if (php_array_existsc (zoptions , "allow_invalid_hostname" )) {
19692000 ssl_opt -> allow_invalid_hostname = php_array_fetchc_bool (zoptions , "allow_invalid_hostname" );
2001+ any_ssl_option_set = true;
19702002 }
19712003
19722004 if (php_array_existsc (zoptions , "weak_cert_validation" )) {
19732005 ssl_opt -> weak_cert_validation = php_array_fetchc_bool (zoptions , "weak_cert_validation" );
2006+ any_ssl_option_set = true;
19742007 } else if (php_array_existsc (zoptions , "allow_self_signed" )) {
19752008 ssl_opt -> weak_cert_validation = php_array_fetchc_bool (zoptions , "allow_self_signed" );
2009+ any_ssl_option_set = true;
19762010 }
19772011
2012+ #define PHONGO_SSL_OPTION_SWAP_STRING (o , n ) \
2013+ if ((o)) { \
2014+ efree((char*) (o)); \
2015+ } \
2016+ (o) = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL((n)));
2017+
19782018 if (php_array_existsc (zoptions , "pem_file" )) {
1979- ssl_opt -> pem_file = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ("pem_file" ));
2019+ PHONGO_SSL_OPTION_SWAP_STRING (ssl_opt -> pem_file , "pem_file" );
2020+ any_ssl_option_set = true;
19802021 } else if (php_array_existsc (zoptions , "local_cert" )) {
1981- ssl_opt -> pem_file = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ("local_cert" ));
2022+ PHONGO_SSL_OPTION_SWAP_STRING (ssl_opt -> pem_file , "local_cert" );
2023+ any_ssl_option_set = true;
19822024 }
19832025
19842026 if (php_array_existsc (zoptions , "pem_pwd" )) {
1985- ssl_opt -> pem_pwd = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ("pem_pwd" ));
2027+ PHONGO_SSL_OPTION_SWAP_STRING (ssl_opt -> pem_pwd , "pem_pwd" );
2028+ any_ssl_option_set = true;
19862029 } else if (php_array_existsc (zoptions , "passphrase" )) {
1987- ssl_opt -> pem_pwd = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ("passphrase" ));
2030+ PHONGO_SSL_OPTION_SWAP_STRING (ssl_opt -> pem_pwd , "passphrase" );
2031+ any_ssl_option_set = true;
19882032 }
19892033
19902034 if (php_array_existsc (zoptions , "ca_file" )) {
1991- ssl_opt -> ca_file = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ("ca_file" ));
2035+ PHONGO_SSL_OPTION_SWAP_STRING (ssl_opt -> ca_file , "ca_file" );
2036+ any_ssl_option_set = true;
19922037 } else if (php_array_existsc (zoptions , "cafile" )) {
1993- ssl_opt -> ca_file = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ("cafile" ));
2038+ PHONGO_SSL_OPTION_SWAP_STRING (ssl_opt -> ca_file , "cafile" );
2039+ any_ssl_option_set = true;
19942040 }
19952041
19962042 if (php_array_existsc (zoptions , "ca_dir" )) {
1997- ssl_opt -> ca_dir = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ("ca_dir" ));
2043+ PHONGO_SSL_OPTION_SWAP_STRING (ssl_opt -> ca_dir , "ca_dir" );
2044+ any_ssl_option_set = true;
19982045 } else if (php_array_existsc (zoptions , "capath" )) {
1999- ssl_opt -> ca_dir = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ("capath" ));
2046+ PHONGO_SSL_OPTION_SWAP_STRING (ssl_opt -> ca_dir , "capath" );
2047+ any_ssl_option_set = true;
20002048 }
20012049
20022050 if (php_array_existsc (zoptions , "crl_file" )) {
2003- ssl_opt -> crl_file = php_phongo_fetch_ssl_opt_string (zoptions , ZEND_STRL ("crl_file" ));
2051+ PHONGO_SSL_OPTION_SWAP_STRING (ssl_opt -> crl_file , "crl_file" );
2052+ any_ssl_option_set = true;
2053+ }
2054+
2055+ #undef PHONGO_SSL_OPTION_SWAP_STRING
2056+
2057+ if (!any_ssl_option_set ) {
2058+ efree (ssl_opt );
2059+ return NULL ;
20042060 }
20052061
20062062 return ssl_opt ;
@@ -2418,7 +2474,7 @@ void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string,
24182474 }
24192475
24202476#ifdef MONGOC_ENABLE_SSL
2421- ssl_opt = php_phongo_make_ssl_opt (driverOptions TSRMLS_CC );
2477+ ssl_opt = php_phongo_make_ssl_opt (uri , driverOptions TSRMLS_CC );
24222478
24232479 /* An exception may be thrown during SSL option creation */
24242480 if (EG (exception )) {
0 commit comments