Skip to content

Commit 64259e2

Browse files
committed
Merge pull request #1013
2 parents 929e2ca + ef16f97 commit 64259e2

File tree

4 files changed

+199
-48
lines changed

4 files changed

+199
-48
lines changed

php_phongo.c

Lines changed: 126 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,25 @@ static bool php_phongo_uri_finalize_auth(mongoc_uri_t* uri TSRMLS_DC) /* {{{ */
15001500
return true;
15011501
} /* }}} */
15021502

1503+
static bool php_phongo_uri_finalize_tls(mongoc_uri_t* uri TSRMLS_DC) /* {{{ */
1504+
{
1505+
const bson_t *options;
1506+
bson_iter_t iter;
1507+
1508+
if (!(options = mongoc_uri_get_options(uri))) {
1509+
return true;
1510+
}
1511+
1512+
if (bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSINSECURE) &&
1513+
(bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES) ||
1514+
bson_iter_init_find_case(&iter, options, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES))) {
1515+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse URI options: %s may not be combined with %s or %s.", MONGOC_URI_TLSINSECURE, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES);
1516+
return false;
1517+
}
1518+
1519+
return true;
1520+
} /* }}} */
1521+
15031522
static bool php_phongo_apply_options_to_uri(mongoc_uri_t* uri, bson_t* options TSRMLS_DC) /* {{{ */
15041523
{
15051524
bson_iter_t iter;
@@ -2049,15 +2068,16 @@ static bool php_phongo_apply_wc_options_to_uri(mongoc_uri_t* uri, bson_t* option
20492068

20502069
static void php_phongo_mongoc_ssl_opts_from_uri(mongoc_ssl_opt_t* ssl_opt, mongoc_uri_t* uri, bool* any_ssl_option_set)
20512070
{
2052-
const char* pem_file = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_SSLCLIENTCERTIFICATEKEYFILE, NULL);
2053-
const char* pem_pwd = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_SSLCLIENTCERTIFICATEKEYPASSWORD, NULL);
2054-
const char* ca_file = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_SSLCERTIFICATEAUTHORITYFILE, NULL);
2071+
bool insecure = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_TLSINSECURE, false);
2072+
const char* pem_file = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, NULL);
2073+
const char* pem_pwd = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD, NULL);
2074+
const char* ca_file = mongoc_uri_get_option_as_utf8(uri, MONGOC_URI_TLSCAFILE, NULL);
20552075

20562076
ssl_opt->pem_file = pem_file ? estrdup(pem_file) : NULL;
20572077
ssl_opt->pem_pwd = pem_pwd ? estrdup(pem_pwd) : NULL;
20582078
ssl_opt->ca_file = ca_file ? estrdup(ca_file) : NULL;
2059-
ssl_opt->weak_cert_validation = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_SSLALLOWINVALIDCERTIFICATES, false);
2060-
ssl_opt->allow_invalid_hostname = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_SSLALLOWINVALIDHOSTNAMES, false);
2079+
ssl_opt->weak_cert_validation = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, insecure);
2080+
ssl_opt->allow_invalid_hostname = mongoc_uri_get_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, insecure);
20612081

20622082
/* Boolean options default to false, so we cannot consider them for
20632083
* any_ssl_option_set. This isn't actually a problem as libmongoc will
@@ -2069,14 +2089,14 @@ static void php_phongo_mongoc_ssl_opts_from_uri(mongoc_ssl_opt_t* ssl_opt, mongo
20692089
}
20702090
}
20712091

2072-
static inline char* php_phongo_fetch_ssl_opt_string(zval* zoptions, const char* key, int key_len)
2092+
static inline char* php_phongo_fetch_ssl_opt_string(zval* zoptions, const char* key)
20732093
{
20742094
int plen;
20752095
zend_bool pfree;
20762096
char* pval;
20772097
char* value;
20782098

2079-
pval = php_array_fetchl_string(zoptions, key, key_len, &plen, &pfree);
2099+
pval = php_array_fetch_string(zoptions, key, &plen, &pfree);
20802100
value = pfree ? pval : estrndup(pval, plen);
20812101

20822102
return value;
@@ -2119,51 +2139,14 @@ static mongoc_ssl_opt_t* php_phongo_make_ssl_opt(mongoc_uri_t* uri, zval* zoptio
21192139
php_phongo_mongoc_ssl_opts_from_uri(ssl_opt, uri, &any_ssl_option_set);
21202140
}
21212141

2122-
/* Check canonical option names first and fall back to SSL context options
2123-
* for backwards compatibility. */
2124-
if (php_array_existsc(zoptions, "allow_invalid_hostname")) {
2125-
ssl_opt->allow_invalid_hostname = php_array_fetchc_bool(zoptions, "allow_invalid_hostname");
2126-
any_ssl_option_set = true;
2127-
}
2128-
2129-
if (php_array_existsc(zoptions, "weak_cert_validation")) {
2130-
ssl_opt->weak_cert_validation = php_array_fetchc_bool(zoptions, "weak_cert_validation");
2131-
any_ssl_option_set = true;
2132-
} else if (php_array_existsc(zoptions, "allow_self_signed")) {
2133-
ssl_opt->weak_cert_validation = php_array_fetchc_bool(zoptions, "allow_self_signed");
2134-
any_ssl_option_set = true;
2135-
}
2136-
21372142
#define PHONGO_SSL_OPTION_SWAP_STRING(o, n) \
21382143
if ((o)) { \
21392144
efree((char*) (o)); \
21402145
} \
2141-
(o) = php_phongo_fetch_ssl_opt_string(zoptions, ZEND_STRL((n)));
2142-
2143-
if (php_array_existsc(zoptions, "pem_file")) {
2144-
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->pem_file, "pem_file");
2145-
any_ssl_option_set = true;
2146-
} else if (php_array_existsc(zoptions, "local_cert")) {
2147-
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->pem_file, "local_cert");
2148-
any_ssl_option_set = true;
2149-
}
2150-
2151-
if (php_array_existsc(zoptions, "pem_pwd")) {
2152-
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->pem_pwd, "pem_pwd");
2153-
any_ssl_option_set = true;
2154-
} else if (php_array_existsc(zoptions, "passphrase")) {
2155-
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->pem_pwd, "passphrase");
2156-
any_ssl_option_set = true;
2157-
}
2158-
2159-
if (php_array_existsc(zoptions, "ca_file")) {
2160-
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->ca_file, "ca_file");
2161-
any_ssl_option_set = true;
2162-
} else if (php_array_existsc(zoptions, "cafile")) {
2163-
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->ca_file, "cafile");
2164-
any_ssl_option_set = true;
2165-
}
2146+
(o) = php_phongo_fetch_ssl_opt_string(zoptions, n);
21662147

2148+
/* Apply driver options that don't have a corresponding URI option. These
2149+
* are set directly on the SSL options struct. */
21672150
if (php_array_existsc(zoptions, "ca_dir")) {
21682151
PHONGO_SSL_OPTION_SWAP_STRING(ssl_opt->ca_dir, "ca_dir");
21692152
any_ssl_option_set = true;
@@ -2211,6 +2194,92 @@ static void php_phongo_free_ssl_opt(mongoc_ssl_opt_t* ssl_opt)
22112194

22122195
efree(ssl_opt);
22132196
}
2197+
2198+
static inline bool php_phongo_apply_driver_option_to_uri(mongoc_uri_t* uri, zval* zoptions, const char* driverOptionKey, const char* optionKey)
2199+
{
2200+
bool ret;
2201+
char* value;
2202+
2203+
value = php_phongo_fetch_ssl_opt_string(zoptions, driverOptionKey);
2204+
ret = mongoc_uri_set_option_as_utf8(uri, optionKey, value);
2205+
efree(value);
2206+
2207+
return ret;
2208+
}
2209+
2210+
static bool php_phongo_apply_driver_options_to_uri(mongoc_uri_t* uri, zval* zoptions TSRMLS_DC)
2211+
{
2212+
if (!zoptions) {
2213+
return true;
2214+
}
2215+
2216+
/* Map TLS driver options to the canonical tls options in the URI. */
2217+
if (php_array_existsc(zoptions, "allow_invalid_hostname")) {
2218+
if (!mongoc_uri_set_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDHOSTNAMES, php_array_fetchc_bool(zoptions, "allow_invalid_hostname"))) {
2219+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "allow_invalid_hostname");
2220+
2221+
return false;
2222+
}
2223+
}
2224+
2225+
if (php_array_existsc(zoptions, "weak_cert_validation")) {
2226+
if (!mongoc_uri_set_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, php_array_fetchc_bool(zoptions, "weak_cert_validation"))) {
2227+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "weak_cert_validation");
2228+
2229+
return false;
2230+
}
2231+
} else if (php_array_existsc(zoptions, "allow_self_signed")) {
2232+
if (!mongoc_uri_set_option_as_bool(uri, MONGOC_URI_TLSALLOWINVALIDCERTIFICATES, php_array_fetchc_bool(zoptions, "allow_self_signed"))) {
2233+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "allow_self_signed");
2234+
2235+
return false;
2236+
}
2237+
}
2238+
2239+
if (php_array_existsc(zoptions, "pem_file")) {
2240+
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "pem_file", MONGOC_URI_TLSCERTIFICATEKEYFILE)) {
2241+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "pem_file");
2242+
2243+
return false;
2244+
}
2245+
} else if (php_array_existsc(zoptions, "local_cert")) {
2246+
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "local_cert", MONGOC_URI_TLSCERTIFICATEKEYFILE)) {
2247+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "local_cert");
2248+
2249+
return false;
2250+
}
2251+
}
2252+
2253+
if (php_array_existsc(zoptions, "pem_pwd")) {
2254+
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "pem_pwd", MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD)) {
2255+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "pem_pwd");
2256+
2257+
return false;
2258+
}
2259+
} else if (php_array_existsc(zoptions, "passphrase")) {
2260+
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "passphrase", MONGOC_URI_TLSCERTIFICATEKEYFILEPASSWORD)) {
2261+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "passphrase");
2262+
2263+
return false;
2264+
}
2265+
}
2266+
2267+
if (php_array_existsc(zoptions, "ca_file")) {
2268+
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "ca_file", MONGOC_URI_TLSCAFILE)) {
2269+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "ca_file");
2270+
2271+
return false;
2272+
}
2273+
} else if (php_array_existsc(zoptions, "cafile")) {
2274+
if (!php_phongo_apply_driver_option_to_uri(uri, zoptions, "cafile", MONGOC_URI_TLSCAFILE)) {
2275+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse \"%s\" driver option", "cafile");
2276+
2277+
return false;
2278+
}
2279+
}
2280+
2281+
return true;
2282+
}
22142283
#endif
22152284

22162285
/* APM callbacks */
@@ -2599,12 +2668,22 @@ void phongo_manager_init(php_phongo_manager_t* manager, const char* uri_string,
25992668
}
26002669

26012670
#ifdef MONGOC_ENABLE_SSL
2671+
if (!php_phongo_apply_driver_options_to_uri(uri, driverOptions TSRMLS_CC)) {
2672+
/* Exception should already have been thrown */
2673+
goto cleanup;
2674+
}
2675+
26022676
ssl_opt = php_phongo_make_ssl_opt(uri, driverOptions TSRMLS_CC);
26032677

26042678
/* An exception may be thrown during SSL option creation */
26052679
if (EG(exception)) {
26062680
goto cleanup;
26072681
}
2682+
2683+
if (!php_phongo_uri_finalize_tls(uri TSRMLS_CC)) {
2684+
/* Exception should already have been thrown */
2685+
goto cleanup;
2686+
}
26082687
#else
26092688
if (mongoc_uri_get_tls(uri)) {
26102689
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Cannot create SSL client. SSL is not enabled in this build.");
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
MongoDB\Driver\Manager::__construct(): tlsInsecure cannot be combined with tlsAllowInvalidHostnames
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/tools.php';
7+
8+
echo throws(function() {
9+
new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidHostnames=true');
10+
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
11+
12+
echo throws(function() {
13+
new MongoDB\Driver\Manager('mongodb://localhost:27017/', ['tlsInsecure' => true, 'tlsAllowInvalidHostnames' => true]);
14+
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
15+
16+
echo throws(function() {
17+
new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsInsecure=true', ['tlsAllowInvalidHostnames' => true]);
18+
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
19+
20+
echo throws(function() {
21+
new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsAllowInvalidHostnames=true', ['tlsInsecure' => true]);
22+
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
23+
24+
?>
25+
===DONE===
26+
<?php exit(0); ?>
27+
--EXPECT--
28+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
29+
Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidHostnames=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
30+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
31+
Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
32+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
33+
Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
34+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
35+
Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
36+
===DONE===
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
MongoDB\Driver\Manager::__construct(): tlsInsecure cannot be combined with tlsAllowInvalidCertificates
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/tools.php';
7+
8+
echo throws(function() {
9+
new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidCertificates=true');
10+
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
11+
12+
echo throws(function() {
13+
new MongoDB\Driver\Manager('mongodb://localhost:27017/', ['tlsInsecure' => true, 'tlsAllowInvalidCertificates' => true]);
14+
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
15+
16+
echo throws(function() {
17+
new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsInsecure=true', ['tlsAllowInvalidCertificates' => true]);
18+
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
19+
20+
echo throws(function() {
21+
new MongoDB\Driver\Manager('mongodb://localhost:27017/?tlsAllowInvalidCertificates=true', ['tlsInsecure' => true]);
22+
}, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n";
23+
24+
?>
25+
===DONE===
26+
<?php exit(0); ?>
27+
--EXPECT--
28+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
29+
Failed to parse MongoDB URI: 'mongodb://localhost:27017/?tlsInsecure=true&tlsAllowInvalidCertificates=true'. tlsinsecure may not be specified with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
30+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
31+
Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
32+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
33+
Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
34+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
35+
Failed to parse URI options: tlsinsecure may not be combined with tlsallowinvalidcertificates or tlsallowinvalidhostnames.
36+
===DONE===

tests/utils/tools.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ function is_auth($uri)
266266
*/
267267
function is_ssl($uri)
268268
{
269-
return stripos($uri, 'ssl=true') !== false;
269+
return stripos($uri, 'ssl=true') !== false || stripos($uri, 'tls=true') !== false;
270270
}
271271

272272
/**

0 commit comments

Comments
 (0)