summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoxie Linden <roxie@lindenlab.com>2010-04-26 17:41:21 -0700
committerRoxie Linden <roxie@lindenlab.com>2010-04-26 17:41:21 -0700
commitd82a10217ad5ac09500e272b74cdacb4bf04414b (patch)
tree3ab2f46f116e355c0643ef96e8342564f4cf6902
parenta42dcc3f5e8dbddbc83500371bcb3d0ca8d91a3b (diff)
Fix issue parsing wildcard cns in certificates
CR: Karina
-rw-r--r--indra/newview/llsechandler_basic.cpp46
-rw-r--r--indra/newview/tests/llsechandler_basic_test.cpp31
2 files changed, 62 insertions, 15 deletions
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 51e250ffc6..df55ccf142 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -782,23 +782,49 @@ bool _cert_hostname_wildcard_match(const std::string& hostname, const std::strin
{
std::string new_hostname = hostname;
std::string new_cn = common_name;
- int subdomain_pos = new_hostname.find_first_of('.');
- int subcn_pos = new_cn.find_first_of('.');
- while((subcn_pos != std::string::npos) && (subdomain_pos != std::string::npos))
+ // find the last '.' in the hostname and the match name.
+ int subdomain_pos = new_hostname.find_last_of('.');
+ int subcn_pos = new_cn.find_last_of('.');
+
+ // if the last char is a '.', strip it
+ if(subdomain_pos == (new_hostname.length()-1))
+ {
+ new_hostname = new_hostname.substr(0, subdomain_pos);
+ subdomain_pos = new_hostname.find_last_of('.');
+ }
+ if(subcn_pos == (new_cn.length()-1))
{
- // snip out the first subdomain and cn element
+ new_cn = new_cn.substr(0, subcn_pos);
+ subcn_pos = new_cn.find_last_of('.');
+ }
- if(!_cert_subdomain_wildcard_match(new_hostname.substr(0, subdomain_pos),
- new_cn.substr(0, subcn_pos)))
+ // Check to see if there are any further '.' in the string.
+ while((subcn_pos != std::string::npos) && (subdomain_pos != std::string::npos))
+ {
+ // snip out last subdomain in both the match string and the hostname
+ // The last bit for 'my.current.host.com' would be 'com'
+ std::string cn_part = new_cn.substr(subcn_pos+1, std::string::npos);
+ std::string hostname_part = new_hostname.substr(subdomain_pos+1, std::string::npos);
+
+ if(!_cert_subdomain_wildcard_match(new_hostname.substr(subdomain_pos+1, std::string::npos),
+ cn_part))
{
return FALSE;
}
- new_hostname = new_hostname.substr(subdomain_pos+1, std::string::npos);
- new_cn = new_cn.substr(subcn_pos+1, std::string::npos);
- subdomain_pos = new_hostname.find_first_of('.');
- subcn_pos = new_cn.find_first_of('.');
+ new_hostname = new_hostname.substr(0, subdomain_pos);
+ new_cn = new_cn.substr(0, subcn_pos);
+ subdomain_pos = new_hostname.find_last_of('.');
+ subcn_pos = new_cn.find_last_of('.');
+ }
+ // check to see if the most significant portion of the common name is '*'. If so, we can
+ // simply return success as child domains are also matched.
+ if(new_cn == "*")
+ {
+ // if it's just a '*' we support all child domains as well, so '*.
+ return TRUE;
}
+
return _cert_subdomain_wildcard_match(new_hostname, new_cn);
}
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index 3f4474e23a..ba448d4b5b 100644
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -702,12 +702,18 @@ namespace tut
{
ensure("simple name match",
_cert_hostname_wildcard_match("foo", "foo"));
-
+
ensure("simple name match, with end period",
_cert_hostname_wildcard_match("foo.", "foo."));
ensure("simple name match, with begin period",
_cert_hostname_wildcard_match(".foo", ".foo"));
+
+ ensure("simple name match, with mismatched period cn",
+ _cert_hostname_wildcard_match("foo.", "foo"));
+
+ ensure("simple name match, with mismatched period hostname",
+ _cert_hostname_wildcard_match("foo", "foo."));
ensure("simple name match, with subdomain",
_cert_hostname_wildcard_match("foo.bar", "foo.bar"));
@@ -772,11 +778,26 @@ namespace tut
ensure("end periods",
_cert_hostname_wildcard_match("foo.bar.com.", "*.b*r.com."));
- ensure("mismatch end period",
- !_cert_hostname_wildcard_match("foo.bar.com.", "*.b*r.com"));
+ ensure("match end period",
+ _cert_hostname_wildcard_match("foo.bar.com.", "*.b*r.com"));
+
+ ensure("match end period2",
+ _cert_hostname_wildcard_match("foo.bar.com", "*.b*r.com."));
+
+ ensure("wildcard mismatch",
+ !_cert_hostname_wildcard_match("bar.com", "*.bar.com"));
+
+ ensure("wildcard match",
+ _cert_hostname_wildcard_match("foo.bar.com", "*.bar.com"));
+
+ ensure("wildcard match",
+ _cert_hostname_wildcard_match("foo.foo.bar.com", "*.bar.com"));
+
+ ensure("wildcard match",
+ _cert_hostname_wildcard_match("foo.foo.bar.com", "*.*.com"));
- ensure("mismatch end period2",
- !_cert_hostname_wildcard_match("foo.bar.com", "*.b*r.com."));
+ ensure("wildcard mismatch",
+ !_cert_hostname_wildcard_match("foo.foo.bar.com", "*.foo.com"));
}
// test cert chain