From 1ad46b5cd0fcac0d3224d37d555092258593eabd Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Mon, 24 May 2010 13:59:10 -0700 Subject: DEV-50173 - investigate certificate code performance DEV-50166 - LLBasicCertificateChain::validate calls in log Added caching of certificates that have been validated. The sha1 hash for the certificate is stored and is associated with the from and to times. When the certificate is validated, the code determines whether the certificate has successfully been validated before by looking for it in the cache, and then checks the date of the cert. If that is successful, the validation calls with success. Otherwise, it proceeds to do a full validation of the certificate. --- indra/newview/llsecapi.cpp | 2 +- indra/newview/llsecapi.h | 31 ++++--- indra/newview/llsechandler_basic.cpp | 114 +++++++++++++++++------- indra/newview/llsechandler_basic.h | 23 +++-- indra/newview/llstartup.cpp | 3 +- indra/newview/llxmlrpctransaction.cpp | 3 +- indra/newview/tests/llsechandler_basic_test.cpp | 34 +++---- 7 files changed, 134 insertions(+), 76 deletions(-) diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp index 1caeec5b04..9e636f38c0 100644 --- a/indra/newview/llsecapi.cpp +++ b/indra/newview/llsecapi.cpp @@ -124,7 +124,7 @@ int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param) // we rely on libcurl to validate the hostname, as libcurl does more extensive validation // leaving our hostname validation call mechanism for future additions with respect to // OS native (Mac keyring, windows CAPI) validation. - chain->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), store, validation_params); + store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params); } catch (LLCertValidationTrustException& cert_exception) { diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h index 59a1e1eff0..5a1a3879d4 100644 --- a/indra/newview/llsecapi.h +++ b/indra/newview/llsecapi.h @@ -154,7 +154,7 @@ public: // return an LLSD object containing information about the certificate // such as its name, signature, expiry time, serial number - virtual LLSD getLLSD() const=0; + virtual void getLLSD(LLSD& llsd)=0; // return an openSSL X509 struct for the certificate virtual X509* getOpenSSLX509() const=0; @@ -231,6 +231,18 @@ public: virtual LLPointer erase(iterator cert)=0; }; +// class LLCertificateChain +// Class representing a chain of certificates in order, with the +// first element being the child cert. +class LLCertificateChain : virtual public LLCertificateVector +{ + +public: + LLCertificateChain() {} + + virtual ~LLCertificateChain() {} + +}; // class LLCertificateStore // represents a store of certificates, typically a store of root CA @@ -250,30 +262,17 @@ public: // return the store id virtual std::string storeId() const=0; -}; - -// class LLCertificateChain -// Class representing a chain of certificates in order, with the -// first element being the child cert. -class LLCertificateChain : virtual public LLCertificateVector -{ - -public: - LLCertificateChain() {} - virtual ~LLCertificateChain() {} - // validate a certificate chain given the params. // Will throw exceptions on error virtual void validate(int validation_policy, - LLPointer ca_store, + LLPointer cert_chain, const LLSD& validation_params) =0; + }; - - inline bool operator==(const LLCertificateVector::iterator& _lhs, const LLCertificateVector::iterator& _rhs) { diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index edf5ce9b60..84ab9b9175 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -85,7 +85,6 @@ LLBasicCertificate::LLBasicCertificate(const std::string& pem_cert) { throw LLInvalidCertificate(this); } - _initLLSD(); } @@ -96,7 +95,6 @@ LLBasicCertificate::LLBasicCertificate(X509* pCert) throw LLInvalidCertificate(this); } mCert = X509_dup(pCert); - _initLLSD(); } LLBasicCertificate::~LLBasicCertificate() @@ -150,9 +148,13 @@ std::vector LLBasicCertificate::getBinary() const } -LLSD LLBasicCertificate::getLLSD() const +void LLBasicCertificate::getLLSD(LLSD &llsd) { - return mLLSDInfo; + if (mLLSDInfo.isUndefined()) + { + _initLLSD(); + } + llsd = mLLSDInfo; } // Initialize the LLSD info for the certificate @@ -516,8 +518,9 @@ LLBasicCertificateVector::iterator LLBasicCertificateVector::find(const LLSD& pa cert++) { - found= TRUE; - LLSD cert_info = (*cert)->getLLSD(); + found= TRUE; + LLSD cert_info; + (*cert)->getLLSD(cert_info); for (LLSD::map_const_iterator param = params.beginMap(); param != params.endMap(); param++) @@ -543,7 +546,8 @@ LLBasicCertificateVector::iterator LLBasicCertificateVector::find(const LLSD& pa void LLBasicCertificateVector::insert(iterator _iter, LLPointer cert) { - LLSD cert_info = cert->getLLSD(); + LLSD cert_info; + cert->getLLSD(cert_info); if (cert_info.isMap() && cert_info.has(CERT_SHA1_DIGEST)) { LLSD existing_cert_info = LLSD::emptyMap(); @@ -691,7 +695,8 @@ LLBasicCertificateChain::LLBasicCertificateChain(const X509_STORE_CTX* store) while(untrusted_certs.size() > 0) { LLSD find_data = LLSD::emptyMap(); - LLSD cert_data = current->getLLSD(); + LLSD cert_data; + current->getLLSD(cert_data); // we simply build the chain via subject/issuer name as the // client should not have passed in multiple CA's with the same // subject name. If they did, it'll come out in the wash during @@ -850,12 +855,13 @@ bool _LLSDArrayIncludesValue(const LLSD& llsd_set, LLSD llsd_value) } void _validateCert(int validation_policy, - const LLPointer cert, + LLPointer cert, const LLSD& validation_params, int depth) { - LLSD current_cert_info = cert->getLLSD(); + LLSD current_cert_info; + cert->getLLSD(current_cert_info); // check basic properties exist in the cert if(!current_cert_info.has(CERT_SUBJECT_NAME) || !current_cert_info.has(CERT_SUBJECT_NAME_STRING)) { @@ -943,8 +949,9 @@ bool _verify_signature(LLPointer parent, LLPointer child) { bool verify_result = FALSE; - LLSD cert1 = parent->getLLSD(); - LLSD cert2 = child->getLLSD(); + LLSD cert1, cert2; + parent->getLLSD(cert1); + child->getLLSD(cert2); X509 *signing_cert = parent->getOpenSSLX509(); X509 *child_cert = child->getOpenSSLX509(); if((signing_cert != NULL) && (child_cert != NULL)) @@ -979,6 +986,7 @@ bool _verify_signature(LLPointer parent, return verify_result; } + // validate the certificate chain against a store. // There are many aspects of cert validatioin policy involved in // trust validation. The policies in this validation algorithm include @@ -993,8 +1001,8 @@ bool _verify_signature(LLPointer parent, // and verify the last cert is in the certificate store, or points // to a cert in the store. It validates whether any cert in the chain // is trusted in the store, even if it's not the last one. -void LLBasicCertificateChain::validate(int validation_policy, - LLPointer ca_store, +void LLBasicCertificateStore::validate(int validation_policy, + LLPointer cert_chain, const LLSD& validation_params) { @@ -1002,8 +1010,8 @@ void LLBasicCertificateChain::validate(int validation_policy, { throw LLCertException(NULL, "No certs in chain"); } - iterator current_cert = begin(); - LLSD current_cert_info = (*current_cert)->getLLSD(); + iterator current_cert = cert_chain->begin(); + LLSD current_cert_info; LLSD validation_date; if (validation_params.has(CERT_VALIDATION_DATE)) { @@ -1012,6 +1020,7 @@ void LLBasicCertificateChain::validate(int validation_policy, if (validation_policy & VALIDATION_POLICY_HOSTNAME) { + (*current_cert)->getLLSD(current_cert_info); if(!validation_params.has(CERT_HOSTNAME)) { throw LLCertException((*current_cert), "No hostname passed in for validation"); @@ -1021,7 +1030,7 @@ void LLBasicCertificateChain::validate(int validation_policy, throw LLInvalidCertificate((*current_cert)); } - LL_INFOS("SECAPI") << "Validating the hostname " << validation_params[CERT_HOSTNAME].asString() << + LL_DEBUGS("SECAPI") << "Validating the hostname " << validation_params[CERT_HOSTNAME].asString() << "against the cert CN " << current_cert_info[CERT_SUBJECT_NAME][CERT_NAME_CN].asString() << LL_ENDL; if(!_cert_hostname_wildcard_match(validation_params[CERT_HOSTNAME].asString(), current_cert_info[CERT_SUBJECT_NAME][CERT_NAME_CN].asString())) @@ -1030,16 +1039,50 @@ void LLBasicCertificateChain::validate(int validation_policy, (*current_cert)); } } - + // check the cache of already validated certs + X509* cert_x509 = (*current_cert)->getOpenSSLX509(); + if(!cert_x509) + { + throw LLInvalidCertificate((*current_cert)); + } + std::string sha1_hash((const char *)cert_x509->sha1_hash, SHA_DIGEST_LENGTH); + t_cert_cache::iterator cache_entry = mTrustedCertCache.find(sha1_hash); + if(cache_entry != mTrustedCertCache.end()) + { + LL_DEBUGS("SECAPI") << "Found cert in cache" << LL_ENDL; + // this cert is in the cache, so validate the time. + if (validation_policy & VALIDATION_POLICY_TIME) + { + LLDate validation_date(time(NULL)); + if(validation_params.has(CERT_VALIDATION_DATE)) + { + validation_date = validation_params[CERT_VALIDATION_DATE]; + } + + if((validation_date < cache_entry->second.first) || + (validation_date > cache_entry->second.second)) + { + throw LLCertValidationExpirationException((*current_cert), validation_date); + } + } + // successfully found in cache + return; + } + if(current_cert_info.isUndefined()) + { + (*current_cert)->getLLSD(current_cert_info); + } + LLDate from_time = current_cert_info[CERT_VALID_FROM].asDate(); + LLDate to_time = current_cert_info[CERT_VALID_TO].asDate(); int depth = 0; LLPointer previous_cert; // loop through the cert chain, validating the current cert against the next one. - while(current_cert != end()) + while(current_cert != cert_chain->end()) { int local_validation_policy = validation_policy; - if(current_cert == begin()) + if(current_cert == cert_chain->begin()) { // for the child cert, we don't validate CA stuff local_validation_policy &= ~(VALIDATION_POLICY_CA_KU | @@ -1061,23 +1104,23 @@ void LLBasicCertificateChain::validate(int validation_policy, depth); // look for a CA in the CA store that may belong to this chain. - LLSD cert_llsd = (*current_cert)->getLLSD(); LLSD cert_search_params = LLSD::emptyMap(); // is the cert itself in the store? - cert_search_params[CERT_SHA1_DIGEST] = cert_llsd[CERT_SHA1_DIGEST]; - LLCertificateStore::iterator found_store_cert = ca_store->find(cert_search_params); - if(found_store_cert != ca_store->end()) + cert_search_params[CERT_SHA1_DIGEST] = current_cert_info[CERT_SHA1_DIGEST]; + LLCertificateStore::iterator found_store_cert = find(cert_search_params); + if(found_store_cert != end()) { + mTrustedCertCache[sha1_hash] = std::pair(from_time, to_time); return; } // is the parent in the cert store? cert_search_params = LLSD::emptyMap(); - cert_search_params[CERT_SUBJECT_NAME_STRING] = cert_llsd[CERT_ISSUER_NAME_STRING]; - if (cert_llsd.has(CERT_AUTHORITY_KEY_IDENTIFIER)) + cert_search_params[CERT_SUBJECT_NAME_STRING] = current_cert_info[CERT_ISSUER_NAME_STRING]; + if (current_cert_info.has(CERT_AUTHORITY_KEY_IDENTIFIER)) { - LLSD cert_aki = cert_llsd[CERT_AUTHORITY_KEY_IDENTIFIER]; + LLSD cert_aki = current_cert_info[CERT_AUTHORITY_KEY_IDENTIFIER]; if(cert_aki.has(CERT_AUTHORITY_KEY_IDENTIFIER_ID)) { cert_search_params[CERT_SUBJECT_KEY_IDENTFIER] = cert_aki[CERT_AUTHORITY_KEY_IDENTIFIER_ID]; @@ -1087,11 +1130,10 @@ void LLBasicCertificateChain::validate(int validation_policy, cert_search_params[CERT_SERIAL_NUMBER] = cert_aki[CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL]; } } - found_store_cert = ca_store->find(cert_search_params); + found_store_cert = find(cert_search_params); - if(found_store_cert != ca_store->end()) + if(found_store_cert != end()) { - LLSD foo = (*found_store_cert)->getLLSD(); // validate the store cert against the depth _validateCert(validation_policy & VALIDATION_POLICY_CA_BASIC_CONSTRAINTS, (*found_store_cert), @@ -1105,11 +1147,16 @@ void LLBasicCertificateChain::validate(int validation_policy, throw LLCertValidationInvalidSignatureException(*current_cert); } // successfully validated. + mTrustedCertCache[sha1_hash] = std::pair(from_time, to_time); return; } previous_cert = (*current_cert); current_cert++; - depth++; + depth++; + if(current_cert != current_cert != cert_chain->end()) + { + (*current_cert)->getLLSD(current_cert_info); + } } if (validation_policy & VALIDATION_POLICY_TRUSTED) { @@ -1118,6 +1165,7 @@ void LLBasicCertificateChain::validate(int validation_policy, throw LLCertValidationTrustException((*this)[size()-1]); } + mTrustedCertCache[sha1_hash] = std::pair(from_time, to_time); } @@ -1155,7 +1203,7 @@ void LLSecAPIBasicHandler::init() "CA.pem"); - LL_INFOS("SECAPI") << "Loading certificate store from " << store_file << LL_ENDL; + LL_DEBUGS("SECAPI") << "Loading certificate store from " << store_file << LL_ENDL; mStore = new LLBasicCertificateStore(store_file); // grab the application CA.pem file that contains the well-known certs shipped @@ -1465,7 +1513,7 @@ void LLSecAPIBasicHandler::saveCredential(LLPointer cred, bool sav { credential["authenticator"] = cred->getAuthenticator(); } - LL_INFOS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL; + LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL; setProtectedData("credential", cred->getGrid(), credential); //*TODO: If we're saving Agni credentials, should we write the // credentials to the legacy password.dat/etc? diff --git a/indra/newview/llsechandler_basic.h b/indra/newview/llsechandler_basic.h index 4bbb73f062..3ddd36a81a 100644 --- a/indra/newview/llsechandler_basic.h +++ b/indra/newview/llsechandler_basic.h @@ -59,12 +59,13 @@ public: virtual std::string getPem() const; virtual std::vector getBinary() const; - virtual LLSD getLLSD() const; + virtual void getLLSD(LLSD &llsd); virtual X509* getOpenSSLX509() const; // set llsd elements for testing void setLLSD(const std::string name, const LLSD& value) { mLLSDInfo[name] = value; } + protected: // certificates are stored as X509 objects, as validation and @@ -173,8 +174,21 @@ public: // return the store id virtual std::string storeId() const; + // validate a certificate chain against a certificate store, using the + // given validation policy. + virtual void validate(int validation_policy, + LLPointer ca_chain, + const LLSD& validation_params); + protected: - std::vector >mCerts; + std::vector > mCerts; + + // cache of cert sha1 hashes to from/to date pairs, to improve + // performance of cert trust. Note, these are not the CA certs, + // but the certs that have been validated against this store. + typedef std::map > t_cert_cache; + t_cert_cache mTrustedCertCache; + std::string mFilename; }; @@ -189,11 +203,6 @@ public: virtual ~LLBasicCertificateChain() {} - // validate a certificate chain against a certificate store, using the - // given validation policy. - virtual void validate(int validation_policy, - LLPointer ca_store, - const LLSD& validation_params); }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 0a464b3b6c..7022d83868 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2702,7 +2702,8 @@ LLSD transform_cert_args(LLPointer cert) { LLSD args = LLSD::emptyMap(); std::string value; - LLSD cert_info = cert->getLLSD(); + LLSD cert_info; + cert->getLLSD(cert_info); // convert all of the elements in the cert into // args for the xml dialog, so we have flexability to // display various parts of the cert by only modifying diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index da61840761..bc1a48e26a 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -247,7 +247,8 @@ int LLXMLRPCTransaction::Impl::_sslCertVerifyCallback(X509_STORE_CTX *ctx, void validation_params[CERT_HOSTNAME] = uri.hostName(); try { - chain->validate(VALIDATION_POLICY_SSL, store, validation_params); + // don't validate hostname. Let libcurl do it instead. That way, it'll handle redirects + store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params); } catch (LLCertValidationTrustException& cert_exception) { diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp index fd680b24f0..d1330e2270 100644 --- a/indra/newview/tests/llsechandler_basic_test.cpp +++ b/indra/newview/tests/llsechandler_basic_test.cpp @@ -950,15 +950,15 @@ namespace tut test_chain->add(new LLBasicCertificate(mX509IntermediateCert)); - test_chain->validate(0, test_store, validation_params); + test_store->validate(0, test_chain, validation_params); // add the root certificate to the chain and revalidate test_chain->add(new LLBasicCertificate(mX509RootCert)); - test_chain->validate(0, test_store, validation_params); + test_store->validate(0, test_chain, validation_params); // add the child cert at the head of the chain, and revalidate (3 deep chain) test_chain->insert(test_chain->begin(), new LLBasicCertificate(mX509ChildCert)); - test_chain->validate(0, test_store, validation_params); + test_store->validate(0, test_chain, validation_params); // basic failure cases test_chain = new LLBasicCertificateChain(NULL); @@ -967,14 +967,14 @@ namespace tut ensure_throws("no CA, with only a child cert", LLCertValidationTrustException, (*test_chain)[0], - test_chain->validate, + test_store->validate, VALIDATION_POLICY_TRUSTED, - test_store, + test_chain, validation_params); // validate without the trust flag. - test_chain->validate(0, test_store, validation_params); + test_store->validate(0, test_chain, validation_params); // clear out the store test_store = new LLBasicCertificateStore("mycertstore.pem"); @@ -983,9 +983,9 @@ namespace tut ensure_throws("no CA, with child and intermediate certs", LLCertValidationTrustException, (*test_chain)[1], - test_chain->validate, + test_store->validate, VALIDATION_POLICY_TRUSTED, - test_store, + test_chain, validation_params); // validate without the trust flag test_chain->validate(0, test_store, validation_params); @@ -994,7 +994,7 @@ namespace tut LLSD child_info = (*test_chain)[0]->getLLSD(); validation_params = LLSD::emptyMap(); validation_params[CERT_VALIDATION_DATE] = LLDate(child_info[CERT_VALID_FROM].asDate().secondsSinceEpoch() + 1.0); - test_chain->validate(VALIDATION_POLICY_TIME, test_store, validation_params); + test_store->validate(VALIDATION_POLICY_TIME, test_chain, validation_params); validation_params = LLSD::emptyMap(); validation_params[CERT_VALIDATION_DATE] = child_info[CERT_VALID_FROM].asDate(); @@ -1005,9 +1005,9 @@ namespace tut ensure_throws("Child cert not yet valid" , LLCertValidationExpirationException, (*test_chain)[0], - test_chain->validate, + test_store->validate, VALIDATION_POLICY_TIME, - test_store, + test_chain, validation_params); validation_params = LLSD::emptyMap(); validation_params[CERT_VALIDATION_DATE] = LLDate(child_info[CERT_VALID_TO].asDate().secondsSinceEpoch() + 1.0); @@ -1016,9 +1016,9 @@ namespace tut ensure_throws("Child cert expired", LLCertValidationExpirationException, (*test_chain)[0], - test_chain->validate, + test_store->validate, VALIDATION_POLICY_TIME, - test_store, + test_chain, validation_params); // test SSL KU @@ -1026,7 +1026,7 @@ namespace tut test_chain = new LLBasicCertificateChain(NULL); test_chain->add(new LLBasicCertificate(mX509ChildCert)); test_chain->add(new LLBasicCertificate(mX509IntermediateCert)); - test_chain->validate(VALIDATION_POLICY_SSL_KU, test_store, validation_params); + test_store->validate(VALIDATION_POLICY_SSL_KU, test_chain, validation_params); test_chain = new LLBasicCertificateChain(NULL); test_chain->add(new LLBasicCertificate(mX509TestCert)); @@ -1034,9 +1034,9 @@ namespace tut ensure_throws("Cert doesn't have ku", LLCertKeyUsageValidationException, (*test_chain)[0], - test_chain->validate, + test_store->validate, VALIDATION_POLICY_SSL_KU, - test_store, + test_chain, validation_params); // test sha1RSA validation @@ -1044,7 +1044,7 @@ namespace tut test_chain->add(new LLBasicCertificate(mSha1RSATestCert)); test_chain->add(new LLBasicCertificate(mSha1RSATestCA)); - test_chain->validate(0, test_store, validation_params); + test_store->validate(0, test_chain, validation_params); } }; -- cgit v1.2.3 From a7d1c68c787fcccf888632b9787c4cc9b30393f7 Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Mon, 24 May 2010 15:31:10 -0700 Subject: Fixup some certificate related unit tests --- indra/newview/llsechandler_basic.cpp | 2 +- indra/newview/tests/llsechandler_basic_test.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index 84ab9b9175..a81cde3126 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -1153,7 +1153,7 @@ void LLBasicCertificateStore::validate(int validation_policy, previous_cert = (*current_cert); current_cert++; depth++; - if(current_cert != current_cert != cert_chain->end()) + if(current_cert != cert_chain->end()) { (*current_cert)->getLLSD(current_cert_info); } diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp index d1330e2270..dfbd596d39 100644 --- a/indra/newview/tests/llsechandler_basic_test.cpp +++ b/indra/newview/tests/llsechandler_basic_test.cpp @@ -328,7 +328,8 @@ namespace tut ensure_equals("Der Format is correct", memcmp(buffer, mDerFormat.c_str(), mDerFormat.length()), 0); - LLSD llsd_cert = test_cert->getLLSD(); + LLSD llsd_cert; + test_cert->getLLSD(llsd_cert); std::ostringstream llsd_value; llsd_value << LLSDOStreamer(llsd_cert) << std::endl; std::string llsd_cert_str = llsd_value.str(); @@ -988,10 +989,11 @@ namespace tut test_chain, validation_params); // validate without the trust flag - test_chain->validate(0, test_store, validation_params); + test_store->validate(0, test_chain, validation_params); // Test time validity - LLSD child_info = (*test_chain)[0]->getLLSD(); + LLSD child_info; + ((*test_chain)[0])->getLLSD(child_info); validation_params = LLSD::emptyMap(); validation_params[CERT_VALIDATION_DATE] = LLDate(child_info[CERT_VALID_FROM].asDate().secondsSinceEpoch() + 1.0); test_store->validate(VALIDATION_POLICY_TIME, test_chain, validation_params); -- cgit v1.2.3 From 32ad37b3f7ca48564bd15de2664f323ad4a2d367 Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Mon, 24 May 2010 16:21:29 -0700 Subject: Few more touchups for the cert performance code --- indra/newview/llsechandler_basic.cpp | 5 ++--- indra/newview/tests/llsechandler_basic_test.cpp | 10 +++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index a81cde3126..5f24d4398a 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -1006,7 +1006,7 @@ void LLBasicCertificateStore::validate(int validation_policy, const LLSD& validation_params) { - if(size() < 1) + if(cert_chain->size() < 1) { throw LLCertException(NULL, "No certs in chain"); } @@ -1160,9 +1160,8 @@ void LLBasicCertificateStore::validate(int validation_policy, } if (validation_policy & VALIDATION_POLICY_TRUSTED) { - LLPointer untrusted_ca_cert = (*this)[size()-1]; // we reached the end without finding a trusted cert. - throw LLCertValidationTrustException((*this)[size()-1]); + throw LLCertValidationTrustException((*cert_chain)[cert_chain->size()-1]); } mTrustedCertCache[sha1_hash] = std::pair(from_time, to_time); diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp index dfbd596d39..df0673a159 100644 --- a/indra/newview/tests/llsechandler_basic_test.cpp +++ b/indra/newview/tests/llsechandler_basic_test.cpp @@ -963,8 +963,15 @@ namespace tut // basic failure cases test_chain = new LLBasicCertificateChain(NULL); - //validate with only the child cert + //validate with only the child cert in chain, but child cert was previously + // trusted test_chain->add(new LLBasicCertificate(mX509ChildCert)); + + // validate without the trust flag. + test_store->validate(VALIDATION_POLICY_TRUSTED, test_chain, validation_params); + + // Validate with child cert but no parent, and no parent in CA store + test_store = new LLBasicCertificateStore("mycertstore.pem"); ensure_throws("no CA, with only a child cert", LLCertValidationTrustException, (*test_chain)[0], @@ -1033,6 +1040,7 @@ namespace tut test_chain = new LLBasicCertificateChain(NULL); test_chain->add(new LLBasicCertificate(mX509TestCert)); + test_store = new LLBasicCertificateStore("mycertstore.pem"); ensure_throws("Cert doesn't have ku", LLCertKeyUsageValidationException, (*test_chain)[0], -- cgit v1.2.3 From 1f101ee2a3494565275deac8ab63a1a4c6512eb0 Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Thu, 27 May 2010 11:52:39 -0700 Subject: EXT-7388 - --grid command-line argument does nothing QAR-3119 --grid command-line argument does nothing Made --grid specifier case insensitive. Fixed some issues with specifying non-well-known-grids Fixed some issues with specifying --loginuri, --loginpage and --helperuri --- indra/newview/app_settings/logcontrol.xml | 2 + indra/newview/llviewernetwork.cpp | 177 ++++++++++++----------- indra/newview/llviewernetwork.h | 2 +- indra/newview/tests/llviewernetwork_test.cpp | 206 +++++++++++++++++++++------ 4 files changed, 261 insertions(+), 126 deletions(-) diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index d7bb64ce8a..0d27c20d40 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -25,6 +25,7 @@ AppCache Window RenderInit + GridManager @@ -40,6 +41,7 @@ tags + GridManager diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index c76eee80f7..619deaf50b 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -226,11 +226,11 @@ void LLGridManager::initialize(const std::string& grid_file) LLSD grid = grid_itr->second; // TODO: Make sure gridfile specified label is not // a system grid label - LL_INFOS("GridManager") << "reading: " << key_name << LL_ENDL; + LL_DEBUGS("GridManager") << "reading: " << key_name << LL_ENDL; if (mGridList.has(key_name) && mGridList[key_name].has(GRID_IS_SYSTEM_GRID_VALUE)) { - LL_INFOS("GridManager") << "Cannot override grid " << key_name << " as it's a system grid" << LL_ENDL; + LL_DEBUGS("GridManager") << "Cannot override grid " << key_name << " as it's a system grid" << LL_ENDL; // If the system grid does exist in the grids file, and it's marked as a favorite, set it as a favorite. if(grid_itr->second.has(GRID_IS_FAVORITE_VALUE) && grid_itr->second[GRID_IS_FAVORITE_VALUE].asBoolean() ) { @@ -242,7 +242,7 @@ void LLGridManager::initialize(const std::string& grid_file) try { addGrid(grid); - LL_INFOS("GridManager") << "Added grid: " << key_name << LL_ENDL; + LL_DEBUGS("GridManager") << "Added grid: " << key_name << LL_ENDL; } catch (...) { @@ -260,84 +260,90 @@ void LLGridManager::initialize(const std::string& grid_file) std::string cmd_line_grid = gSavedSettings.getString("CmdLineGridChoice"); if(!cmd_line_grid.empty()) { + // try to find the grid assuming the command line parameter is + // the case-insensitive 'label' of the grid. ie 'Agni' mGrid = getGridByLabel(cmd_line_grid); + if(mGrid.empty()) + { + // if we couldn't find it, assume the + // requested grid is the actual grid 'name' or index, + // which would be the dns name of the grid (for non + // linden hosted grids) + // If the grid isn't there, that's ok, as it will be + // automatically added later. + mGrid = cmd_line_grid; + } + + } + else + { + // if a grid was not passed in via the command line, grab it from the CurrentGrid setting. + // if there's no current grid, that's ok as it'll be either set by the value passed + // in via the login uri if that's specified, or will default to maingrid + mGrid = gSavedSettings.getString("CurrentGrid"); + } + + if(mGrid.empty()) + { + // no grid was specified so default to maingrid + LL_DEBUGS("GridManager") << "Setting grid to MAINGRID as no grid has been specified " << LL_ENDL; + mGrid = MAINGRID; + + } + + // generate a 'grid list' entry for any command line parameter overrides + // or setting overides that we'll add to the grid list or override + // any grid list entries with. + LLSD grid = LLSD::emptyMap(); + + bool grid_dirty = false; + if(mGridList.has(mGrid)) + { + grid = mGridList[mGrid]; + } + else + { + grid[GRID_VALUE] = mGrid; + grid_dirty = true; } - LL_INFOS("GridManager") << "Grid Name: " << mGrid << LL_ENDL; - // If a command line login URI was passed in, so we should add the command - // line grid to the list of grids - LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI"); if (cmd_line_login_uri.isString()) { - LL_INFOS("GridManager") << "adding cmd line login uri" << LL_ENDL; - // grab the other related URI values - std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI"); - std::string cmd_line_login_page = gSavedSettings.getString("LoginPage"); - - // we've a cmd line login, so add a grid for the command line, - // overwriting any existing grids - LLSD grid = LLSD::emptyMap(); + grid_dirty = true; grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); grid[GRID_LOGIN_URI_VALUE].append(cmd_line_login_uri); - LL_INFOS("GridManager") << "cmd line login uri: " << cmd_line_login_uri.asString() << LL_ENDL; - LLURI uri(cmd_line_login_uri.asString()); - if (mGrid.empty()) - { - // if a grid name was not passed in via the command line, - // then set the grid name based on the hostname of the - // login uri - mGrid = uri.hostName(); - } - - grid[GRID_VALUE] = mGrid; - - if (mGridList.has(mGrid) && mGridList[mGrid].has(GRID_LABEL_VALUE)) - { - grid[GRID_LABEL_VALUE] = mGridList[mGrid][GRID_LABEL_VALUE]; - } - else - { - grid[GRID_LABEL_VALUE] = mGrid; - } - if(!cmd_line_helper_uri.empty()) - { - grid[GRID_HELPER_URI_VALUE] = cmd_line_helper_uri; - } - - if(!cmd_line_login_page.empty()) - { - grid[GRID_LOGIN_PAGE_VALUE] = cmd_line_login_page; - } - // if the login page, helper URI value, and so on are not specified, - // add grid will generate them. - - // Also, we will override a system grid if values are passed in via the command - // line, for testing. These values will not be remembered though. - if (mGridList.has(mGrid) && mGridList[mGrid].has(GRID_IS_SYSTEM_GRID_VALUE)) - { - grid[GRID_IS_SYSTEM_GRID_VALUE] = TRUE; - } - addGrid(grid); } - // if a grid was not passed in via the command line, grab it from the CurrentGrid setting. - if (mGrid.empty()) + // override the helper uri if it was passed in + std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI"); + if(!cmd_line_helper_uri.empty()) { - - mGrid = gSavedSettings.getString("CurrentGrid"); + grid[GRID_HELPER_URI_VALUE] = cmd_line_helper_uri; + grid_dirty = true; } - - if (mGrid.empty() || !mGridList.has(mGrid)) + + // override the login page if it was passed in + std::string cmd_line_login_page = gSavedSettings.getString("LoginPage"); + if(!cmd_line_login_page.empty()) { - // the grid name was empty, or the grid isn't actually in the list, then set it to the - // appropriate default. - LL_INFOS("GridManager") << "Resetting grid as grid name " << mGrid << " is not in the list" << LL_ENDL; - mGrid = MAINGRID; + grid[GRID_LOGIN_PAGE_VALUE] = cmd_line_login_page; + grid_dirty = true; } - LL_INFOS("GridManager") << "Selected grid is " << mGrid << LL_ENDL; - gSavedSettings.setString("CurrentGrid", mGrid); + + if(grid_dirty) + { + // add the grid with the additional values, or update the + // existing grid if it exists with the given values + addGrid(grid); + } + LL_DEBUGS("GridManager") << "Selected grid is " << mGrid << LL_ENDL; + setGridChoice(mGrid); + if(mGridList[mGrid][GRID_LOGIN_URI_VALUE].isArray()) + { + llinfos << "is array" << llendl; + } } LLGridManager::~LLGridManager() @@ -401,7 +407,7 @@ void LLGridManager::addGrid(LLSD& grid_data) grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_ACCOUNT); } - LL_INFOS("GridManager") << "ADDING: " << grid << LL_ENDL; + LL_DEBUGS("GridManager") << "ADDING: " << grid << LL_ENDL; mGridList[grid] = grid_data; } } @@ -467,6 +473,7 @@ std::map LLGridManager::getKnownGrids(bool favorite_on return result; } + void LLGridManager::setGridChoice(const std::string& grid) { // Set the grid choice based on a string. @@ -477,35 +484,37 @@ void LLGridManager::setGridChoice(const std::string& grid) // loop through. We could do just a hash lookup but we also want to match // on label - for(LLSD::map_iterator grid_iter = mGridList.beginMap(); - grid_iter != mGridList.endMap(); - grid_iter++) + std::string grid_name = grid; + if(!mGridList.has(grid_name)) { - if((grid == grid_iter->first) || - (grid == grid_iter->second[GRID_LABEL_VALUE].asString())) - { - mGrid = grid_iter->second[GRID_VALUE].asString(); - gSavedSettings.setString("CurrentGrid", grid_iter->second[GRID_VALUE]); - return; - - } + // case insensitive + grid_name = getGridByLabel(grid); + } + + if(grid_name.empty()) + { + // the grid was not in the list of grids. + LLSD grid_data = LLSD::emptyMap(); + grid_data[GRID_VALUE] = grid; + addGrid(grid_data); } - LLSD grid_data = LLSD::emptyMap(); - grid_data[GRID_VALUE] = grid; - addGrid(grid_data); mGrid = grid; gSavedSettings.setString("CurrentGrid", grid); } -std::string LLGridManager::getGridByLabel( const std::string &grid_label) +std::string LLGridManager::getGridByLabel( const std::string &grid_label, bool case_sensitive) { for(LLSD::map_iterator grid_iter = mGridList.beginMap(); grid_iter != mGridList.endMap(); grid_iter++) { - if (grid_iter->second.has(GRID_LABEL_VALUE) && (grid_iter->second[GRID_LABEL_VALUE].asString() == grid_label)) + if (grid_iter->second.has(GRID_LABEL_VALUE)) { - return grid_iter->first; + if (0 == (case_sensitive?LLStringUtil::compareStrings(grid_label, grid_iter->second[GRID_LABEL_VALUE].asString()): + LLStringUtil::compareInsensitive(grid_label, grid_iter->second[GRID_LABEL_VALUE].asString()))) + { + return grid_iter->first; + } } } return std::string(); diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h index 0271e7a7a5..a99e32f701 100644 --- a/indra/newview/llviewernetwork.h +++ b/indra/newview/llviewernetwork.h @@ -127,7 +127,7 @@ public: LLSD getGridInfo() { return mGridList[mGrid]; } - std::string getGridByLabel( const std::string &grid_label); + std::string getGridByLabel( const std::string &grid_label, bool case_sensitive = false); bool isSystemGrid(const std::string& grid) { diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp index d819b44564..a3b11e706a 100644 --- a/indra/newview/tests/llviewernetwork_test.cpp +++ b/indra/newview/tests/llviewernetwork_test.cpp @@ -244,35 +244,20 @@ namespace tut template<> template<> void viewerNetworkTestObject::test<3>() { - gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi"; - + // USE --grid command line + // initialize with a known grid + LLSD grid; + gCmdLineGridChoice = "Aditi"; LLGridManager::getInstance()->initialize("grid_test.xml"); // with single login uri specified. std::map known_grids = LLGridManager::getInstance()->getKnownGrids(); - ensure_equals("adding a command line grid increases known grid size", - known_grids.size(), 24); - ensure_equals("Command line grid is added to the list of grids", - known_grids["my.login.uri"], std::string("my.login.uri")); - LLSD grid = LLGridManager::getInstance()->getGridInfo("my.login.uri"); - ensure_equals("Command line grid name is set", - grid[GRID_VALUE].asString(), std::string("my.login.uri")); - ensure_equals("Command line grid label is set", - grid[GRID_LABEL_VALUE].asString(), std::string("my.login.uri")); - ensure("Command line grid login uri is an array", - grid[GRID_LOGIN_URI_VALUE].isArray()); - ensure_equals("Command line grid login uri is set", - grid[GRID_LOGIN_URI_VALUE][0].asString(), - std::string("https://my.login.uri/cgi-bin/login.cgi")); - ensure_equals("Command line grid helper uri is set", - grid[GRID_HELPER_URI_VALUE].asString(), - std::string("https://my.login.uri/helpers/")); - ensure_equals("Command line grid login page is set", - grid[GRID_LOGIN_PAGE_VALUE].asString(), - std::string("http://my.login.uri/app/login/")); - ensure("Command line grid favorite is set", - !grid.has(GRID_IS_FAVORITE_VALUE)); - ensure("Command line grid isn't a system grid", - !grid.has(GRID_IS_SYSTEM_GRID_VALUE)); + ensure_equals("Using a known grid via command line doesn't increase number of known grids", + known_grids.size(), 23); + ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Aditi")); + // initialize with a known grid in lowercase + gCmdLineGridChoice = "agni"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + ensure_equals("getGridLabel", LLGridManager::getInstance()->getGridLabel(), std::string("Agni")); // now try a command line with a custom grid identifier gCmdLineGridChoice = "mycustomgridchoice"; @@ -290,27 +275,166 @@ namespace tut ensure("Custom Command line grid login uri is an array", grid[GRID_LOGIN_URI_VALUE].isArray()); ensure_equals("Custom Command line grid login uri is set", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://mycustomgridchoice/cgi-bin/login.cgi")); + ensure_equals("Custom Command line grid helper uri is set", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://mycustomgridchoice/helpers/")); + ensure_equals("Custom Command line grid login page is set", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://mycustomgridchoice/app/login/")); + } + + // validate override of login uri with cmd line + template<> template<> + void viewerNetworkTestObject::test<4>() + { + // Override with loginuri + // override known grid + LLSD grid; + gCmdLineGridChoice = "Aditi"; + gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + std::map known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Override known grid login uri: No grids are added", + known_grids.size(), 23); + grid = LLGridManager::getInstance()->getGridInfo(); + ensure("Override known grid login uri: login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override known grid login uri: Command line grid login uri is set", grid[GRID_LOGIN_URI_VALUE][0].asString(), std::string("https://my.login.uri/cgi-bin/login.cgi")); + ensure_equals("Override known grid login uri: helper uri is not changed", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/")); + ensure_equals("Override known grid login uri: login page is not set", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://secondlife.com/app/login/")); - // add a helperuri - gCmdLineHelperURI = "myhelperuri"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - grid = LLGridManager::getInstance()->getGridInfo("mycustomgridchoice"); - ensure_equals("Validate command line helper uri", - grid[GRID_HELPER_URI_VALUE].asString(), std::string("myhelperuri")); + // Override with loginuri + // override custom grid + gCmdLineGridChoice = "mycustomgridchoice"; + gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + known_grids = LLGridManager::getInstance()->getKnownGrids(); + grid = LLGridManager::getInstance()->getGridInfo(); + ensure_equals("Override custom grid login uri: Grid is added", + known_grids.size(), 24); + ensure("Override custom grid login uri: login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override custom grid login uri: login uri is set", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://my.login.uri/cgi-bin/login.cgi")); + ensure_equals("Override custom grid login uri: Helper uri is not set", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://mycustomgridchoice/helpers/")); + ensure_equals("Override custom grid login uri: Login page is not set", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://mycustomgridchoice/app/login/")); + } + + // validate override of helper uri with cmd line + template<> template<> + void viewerNetworkTestObject::test<5>() + { + // Override with helperuri + // override known grid + LLSD grid; + gCmdLineGridChoice = "Aditi"; + gCmdLineLoginURI = ""; + gCmdLineHelperURI = "https://my.helper.uri/mycustomhelpers"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + std::map known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Override known grid helper uri: No grids are added", + known_grids.size(), 23); + grid = LLGridManager::getInstance()->getGridInfo(); + ensure("Override known known helper uri: login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override known grid helper uri: login uri is not changed", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi")); + ensure_equals("Override known grid helper uri: helper uri is changed", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://my.helper.uri/mycustomhelpers")); + ensure_equals("Override known grid helper uri: login page is not changed", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://secondlife.com/app/login/")); + + // Override with helperuri + // override custom grid + gCmdLineGridChoice = "mycustomgridchoice"; + gCmdLineHelperURI = "https://my.helper.uri/mycustomhelpers"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Override custom grid helper uri: grids is added", + known_grids.size(), 24); + grid = LLGridManager::getInstance()->getGridInfo(); + ensure("Override custom helper uri: login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override custom grid helper uri: login uri is not changed", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://mycustomgridchoice/cgi-bin/login.cgi")); + ensure_equals("Override custom grid helper uri: helper uri is changed", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://my.helper.uri/mycustomhelpers")); + ensure_equals("Override custom grid helper uri: login page is not changed", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("http://mycustomgridchoice/app/login/")); + } + + // validate overriding of login page via cmd line + template<> template<> + void viewerNetworkTestObject::test<6>() + { + // Override with login page + // override known grid + LLSD grid; + gCmdLineGridChoice = "Aditi"; + gCmdLineHelperURI = ""; + gLoginPage = "myloginpage"; + LLGridManager::getInstance()->initialize("grid_test.xml"); + std::map known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Override known grid login page: No grids are added", + known_grids.size(), 23); + grid = LLGridManager::getInstance()->getGridInfo(); + ensure("Override known grid login page: Command line grid login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override known grid login page: login uri is not changed", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://login.aditi.lindenlab.com/cgi-bin/login.cgi")); + ensure_equals("Override known grid login page: helper uri is not changed", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("http://aditi-secondlife.webdev.lindenlab.com/helpers/")); + ensure_equals("Override known grid login page: login page is changed", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("myloginpage")); - // add a login page + // Override with login page + // override custom grid + gCmdLineGridChoice = "mycustomgridchoice"; gLoginPage = "myloginpage"; - LLGridManager::getInstance()->initialize("grid_test.xml"); - grid = LLGridManager::getInstance()->getGridInfo("mycustomgridchoice"); - ensure_equals("Validate command line helper uri", - grid[GRID_LOGIN_PAGE_VALUE].asString(), std::string("myloginpage")); + LLGridManager::getInstance()->initialize("grid_test.xml"); + known_grids = LLGridManager::getInstance()->getKnownGrids(); + ensure_equals("Override custom grid login page: grids are added", + known_grids.size(), 24); + grid = LLGridManager::getInstance()->getGridInfo(); + ensure("Override custom grid login page: Command line grid login uri is an array", + grid[GRID_LOGIN_URI_VALUE].isArray()); + ensure_equals("Override custom grid login page: login uri is not changed", + grid[GRID_LOGIN_URI_VALUE][0].asString(), + std::string("https://mycustomgridchoice/cgi-bin/login.cgi")); + ensure_equals("Override custom grid login page: helper uri is not changed", + grid[GRID_HELPER_URI_VALUE].asString(), + std::string("https://mycustomgridchoice/helpers/")); + ensure_equals("Override custom grid login page: login page is changed", + grid[GRID_LOGIN_PAGE_VALUE].asString(), + std::string("myloginpage")); + } // validate grid selection template<> template<> - void viewerNetworkTestObject::test<4>() + void viewerNetworkTestObject::test<7>() { LLSD loginURI = LLSD::emptyArray(); LLSD grid = LLSD::emptyMap(); @@ -346,7 +470,7 @@ namespace tut // name based grid population template<> template<> - void viewerNetworkTestObject::test<5>() + void viewerNetworkTestObject::test<8>() { LLGridManager::getInstance()->initialize("grid_test.xml"); LLSD grid = LLSD::emptyMap(); @@ -386,7 +510,7 @@ namespace tut // persistence of the grid list with an empty gridfile. template<> template<> - void viewerNetworkTestObject::test<6>() + void viewerNetworkTestObject::test<9>() { // try with initial grid list without a grid file, // without setting the grid to a saveable favorite. @@ -420,7 +544,7 @@ namespace tut // persistence of the grid file with existing gridfile template<> template<> - void viewerNetworkTestObject::test<7>() + void viewerNetworkTestObject::test<10>() { llofstream gridfile("grid_test.xml"); -- cgit v1.2.3 From cf05f59dd923d623bc50135214a488a29664ab95 Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Thu, 27 May 2010 17:20:29 -0700 Subject: EXT-7388 - --grid command-line argument does nothing Fix up overriding of --loginuri --loginpage --helperuri --- indra/newview/llpanellogin.cpp | 3 +- indra/newview/llurldispatcher.cpp | 3 +- indra/newview/llviewernetwork.cpp | 88 ++++++++++++++++++---------- indra/newview/llviewernetwork.h | 18 ++---- indra/newview/tests/llviewernetwork_test.cpp | 26 ++++---- 5 files changed, 80 insertions(+), 58 deletions(-) diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 0009f7203a..c8dae024cf 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -1164,7 +1164,8 @@ void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe) void LLPanelLogin::updateLoginPanelLinks() { - LLSD grid_data = LLGridManager::getInstance()->getGridInfo(); + LLSD grid_data; + LLGridManager::getInstance()->getGridInfo(grid_data); bool system_grid = grid_data.has(GRID_IS_SYSTEM_GRID_VALUE); // need to call through sInstance, as it's called from onSelectServer, which diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 9efa6c4108..cbaa7248a2 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -215,7 +215,8 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL& LLSD args; args["SLURL"] = slurl.getLocationString(); args["CURRENT_GRID"] = LLGridManager::getInstance()->getGridLabel(); - LLSD grid_info = LLGridManager::getInstance()->getGridInfo(slurl.getGrid()); + LLSD grid_info; + LLGridManager::getInstance()->getGridInfo(slurl.getGrid(), grid_info); if(grid_info.has(GRID_LABEL_VALUE)) { diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 619deaf50b..a81bb2e6f2 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -296,7 +296,6 @@ void LLGridManager::initialize(const std::string& grid_file) // any grid list entries with. LLSD grid = LLSD::emptyMap(); - bool grid_dirty = false; if(mGridList.has(mGrid)) { grid = mGridList[mGrid]; @@ -304,52 +303,53 @@ void LLGridManager::initialize(const std::string& grid_file) else { grid[GRID_VALUE] = mGrid; - grid_dirty = true; + // add the grid with the additional values, or update the + // existing grid if it exists with the given values + addGrid(grid); + } + + LL_DEBUGS("GridManager") << "Selected grid is " << mGrid << LL_ENDL; + setGridChoice(mGrid); + if(mGridList[mGrid][GRID_LOGIN_URI_VALUE].isArray()) + { + llinfos << "is array" << llendl; } +} + +LLGridManager::~LLGridManager() +{ + saveFavorites(); +} + +void LLGridManager::getGridInfo(const std::string &grid, LLSD& grid_info) +{ + + grid_info = mGridList[grid]; + + // override any grid data with the command line info. LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI"); if (cmd_line_login_uri.isString()) - { - grid_dirty = true; - grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); - grid[GRID_LOGIN_URI_VALUE].append(cmd_line_login_uri); + { + grid_info[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray(); + grid_info[GRID_LOGIN_URI_VALUE].append(cmd_line_login_uri); } // override the helper uri if it was passed in std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI"); if(!cmd_line_helper_uri.empty()) { - grid[GRID_HELPER_URI_VALUE] = cmd_line_helper_uri; - grid_dirty = true; + grid_info[GRID_HELPER_URI_VALUE] = cmd_line_helper_uri; } // override the login page if it was passed in std::string cmd_line_login_page = gSavedSettings.getString("LoginPage"); if(!cmd_line_login_page.empty()) { - grid[GRID_LOGIN_PAGE_VALUE] = cmd_line_login_page; - grid_dirty = true; - } - - - if(grid_dirty) - { - // add the grid with the additional values, or update the - // existing grid if it exists with the given values - addGrid(grid); - } - LL_DEBUGS("GridManager") << "Selected grid is " << mGrid << LL_ENDL; - setGridChoice(mGrid); - if(mGridList[mGrid][GRID_LOGIN_URI_VALUE].isArray()) - { - llinfos << "is array" << llendl; - } + grid_info[GRID_LOGIN_PAGE_VALUE] = cmd_line_login_page; + } } -LLGridManager::~LLGridManager() -{ - saveFavorites(); -} // // LLGridManager::addGrid - add a grid to the grid list, populating the needed values @@ -523,6 +523,12 @@ std::string LLGridManager::getGridByLabel( const std::string &grid_label, bool c void LLGridManager::getLoginURIs(std::vector& uris) { uris.clear(); + LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI"); + if (cmd_line_login_uri.isString()) + { + uris.push_back(cmd_line_login_uri); + return; + } for (LLSD::array_iterator llsd_uri = mGridList[mGrid][GRID_LOGIN_URI_VALUE].beginArray(); llsd_uri != mGridList[mGrid][GRID_LOGIN_URI_VALUE].endArray(); llsd_uri++) @@ -531,7 +537,29 @@ void LLGridManager::getLoginURIs(std::vector& uris) } } -bool LLGridManager::isInProductionGrid() +std::string LLGridManager::getHelperURI() +{ + std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI"); + if(!cmd_line_helper_uri.empty()) + { + return cmd_line_helper_uri; + } + return mGridList[mGrid][GRID_HELPER_URI_VALUE]; +} + +std::string LLGridManager::getLoginPage() +{ + // override the login page if it was passed in + std::string cmd_line_login_page = gSavedSettings.getString("LoginPage"); + if(!cmd_line_login_page.empty()) + { + return cmd_line_login_page; + } + + return mGridList[mGrid][GRID_LOGIN_PAGE_VALUE]; +} + +bool LLGridManager::LLGridManager::isInProductionGrid() { // *NOTE:Mani This used to compare GRID_INFO_AGNI to gGridChoice, // but it seems that loginURI trumps that. diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h index a99e32f701..8c3a15b7cf 100644 --- a/indra/newview/llviewernetwork.h +++ b/indra/newview/llviewernetwork.h @@ -89,17 +89,7 @@ public: // by default only return the user visible grids std::map getKnownGrids(bool favorites_only=FALSE); - LLSD getGridInfo(const std::string& grid) - { - if(mGridList.has(grid)) - { - return mGridList[grid]; - } - else - { - return LLSD(); - } - } + void getGridInfo(const std::string& grid, LLSD &grid_info); // current grid management @@ -112,8 +102,8 @@ public: std::string getGridLabel() { return mGridList[mGrid][GRID_LABEL_VALUE]; } std::string getGrid() const { return mGrid; } void getLoginURIs(std::vector& uris); - std::string getHelperURI() {return mGridList[mGrid][GRID_HELPER_URI_VALUE];} - std::string getLoginPage() {return mGridList[mGrid][GRID_LOGIN_PAGE_VALUE];} + std::string getHelperURI(); + std::string getLoginPage(); std::string getGridLoginID() { return mGridList[mGrid][GRID_ID_VALUE]; } std::string getLoginPage(const std::string& grid) { return mGridList[grid][GRID_LOGIN_PAGE_VALUE]; } void getLoginIdentifierTypes(LLSD& idTypes) { idTypes = mGridList[mGrid][GRID_LOGIN_IDENTIFIER_TYPES]; } @@ -125,7 +115,7 @@ public: std::string getAppSLURLBase(const std::string& grid); std::string getAppSLURLBase() { return getAppSLURLBase(mGrid); } - LLSD getGridInfo() { return mGridList[mGrid]; } + void getGridInfo(LLSD &grid_info) { getGridInfo(mGrid, grid_info); } std::string getGridByLabel( const std::string &grid_label, bool case_sensitive = false); diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp index a3b11e706a..5fba5eb69c 100644 --- a/indra/newview/tests/llviewernetwork_test.cpp +++ b/indra/newview/tests/llviewernetwork_test.cpp @@ -148,7 +148,8 @@ namespace tut known_grids[std::string("util.agni.lindenlab.com")], std::string("Agni")); ensure_equals("None exists", known_grids[""], "None"); - LLSD grid = LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com"); + LLSD grid; + LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com", grid); ensure("Grid info for agni is a map", grid.isMap()); ensure_equals("name is correct for agni", grid[GRID_VALUE].asString(), std::string("util.agni.lindenlab.com")); @@ -190,7 +191,8 @@ namespace tut // assure Agni doesn't get overwritten - LLSD grid = LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com"); + LLSD grid; + LLGridManager::getInstance()->getGridInfo("util.agni.lindenlab.com", grid); ensure_equals("Agni grid label was not modified by grid file", grid[GRID_LABEL_VALUE].asString(), std::string("Agni")); @@ -215,7 +217,7 @@ namespace tut ensure_equals("Grid file adds to name<->label map", known_grids["grid1"], std::string("mylabel")); - grid = LLGridManager::getInstance()->getGridInfo("grid1"); + LLGridManager::getInstance()->getGridInfo("grid1", grid); ensure_equals("grid file grid name is set", grid[GRID_VALUE].asString(), std::string("grid1")); ensure_equals("grid file label is set", @@ -267,7 +269,7 @@ namespace tut known_grids.size(), 24); ensure_equals("Custom Command line grid is added to the list of grids", known_grids["mycustomgridchoice"], std::string("mycustomgridchoice")); - grid = LLGridManager::getInstance()->getGridInfo("mycustomgridchoice"); + LLGridManager::getInstance()->getGridInfo("mycustomgridchoice", grid); ensure_equals("Custom Command line grid name is set", grid[GRID_VALUE].asString(), std::string("mycustomgridchoice")); ensure_equals("Custom Command line grid label is set", @@ -298,7 +300,7 @@ namespace tut std::map known_grids = LLGridManager::getInstance()->getKnownGrids(); ensure_equals("Override known grid login uri: No grids are added", known_grids.size(), 23); - grid = LLGridManager::getInstance()->getGridInfo(); + LLGridManager::getInstance()->getGridInfo(grid); ensure("Override known grid login uri: login uri is an array", grid[GRID_LOGIN_URI_VALUE].isArray()); ensure_equals("Override known grid login uri: Command line grid login uri is set", @@ -317,7 +319,7 @@ namespace tut gCmdLineLoginURI = "https://my.login.uri/cgi-bin/login.cgi"; LLGridManager::getInstance()->initialize("grid_test.xml"); known_grids = LLGridManager::getInstance()->getKnownGrids(); - grid = LLGridManager::getInstance()->getGridInfo(); + LLGridManager::getInstance()->getGridInfo(grid); ensure_equals("Override custom grid login uri: Grid is added", known_grids.size(), 24); ensure("Override custom grid login uri: login uri is an array", @@ -347,7 +349,7 @@ namespace tut std::map known_grids = LLGridManager::getInstance()->getKnownGrids(); ensure_equals("Override known grid helper uri: No grids are added", known_grids.size(), 23); - grid = LLGridManager::getInstance()->getGridInfo(); + LLGridManager::getInstance()->getGridInfo(grid); ensure("Override known known helper uri: login uri is an array", grid[GRID_LOGIN_URI_VALUE].isArray()); ensure_equals("Override known grid helper uri: login uri is not changed", @@ -368,7 +370,7 @@ namespace tut known_grids = LLGridManager::getInstance()->getKnownGrids(); ensure_equals("Override custom grid helper uri: grids is added", known_grids.size(), 24); - grid = LLGridManager::getInstance()->getGridInfo(); + LLGridManager::getInstance()->getGridInfo(grid); ensure("Override custom helper uri: login uri is an array", grid[GRID_LOGIN_URI_VALUE].isArray()); ensure_equals("Override custom grid helper uri: login uri is not changed", @@ -396,7 +398,7 @@ namespace tut std::map known_grids = LLGridManager::getInstance()->getKnownGrids(); ensure_equals("Override known grid login page: No grids are added", known_grids.size(), 23); - grid = LLGridManager::getInstance()->getGridInfo(); + LLGridManager::getInstance()->getGridInfo(grid); ensure("Override known grid login page: Command line grid login uri is an array", grid[GRID_LOGIN_URI_VALUE].isArray()); ensure_equals("Override known grid login page: login uri is not changed", @@ -417,7 +419,7 @@ namespace tut known_grids = LLGridManager::getInstance()->getKnownGrids(); ensure_equals("Override custom grid login page: grids are added", known_grids.size(), 24); - grid = LLGridManager::getInstance()->getGridInfo(); + LLGridManager::getInstance()->getGridInfo(grid); ensure("Override custom grid login page: Command line grid login uri is an array", grid[GRID_LOGIN_URI_VALUE].isArray()); ensure_equals("Override custom grid login page: login uri is not changed", @@ -464,7 +466,7 @@ namespace tut ensure("Is myaddedgrid a production grid", !LLGridManager::getInstance()->isInProductionGrid()); LLGridManager::getInstance()->setFavorite(); - grid = LLGridManager::getInstance()->getGridInfo("myaddedgrid"); + LLGridManager::getInstance()->getGridInfo("myaddedgrid", grid); ensure("setting favorite", grid.has(GRID_IS_FAVORITE_VALUE)); } @@ -477,7 +479,7 @@ namespace tut // adding a grid with simply a name will populate the values. grid[GRID_VALUE] = "myaddedgrid"; LLGridManager::getInstance()->addGrid(grid); - grid = LLGridManager::getInstance()->getGridInfo("myaddedgrid"); + LLGridManager::getInstance()->getGridInfo("myaddedgrid", grid); ensure_equals("name based grid has name value", grid[GRID_VALUE].asString(), -- cgit v1.2.3