PageRenderTime 40ms CodeModel.GetById 25ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llsecapi.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 192 lines | 126 code | 22 blank | 44 comment | 14 complexity | 602a363e7cb8c65777542bc7520d1fee MD5 | raw file
  1/** 
  2 * @file llsecapi.cpp
  3 * @brief Security API for services such as certificate handling
  4 * secure local storage, etc.
  5 *
  6 * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  7 * Second Life Viewer Source Code
  8 * Copyright (C) 2010, Linden Research, Inc.
  9 * 
 10 * This library is free software; you can redistribute it and/or
 11 * modify it under the terms of the GNU Lesser General Public
 12 * License as published by the Free Software Foundation;
 13 * version 2.1 of the License only.
 14 * 
 15 * This library is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 18 * Lesser General Public License for more details.
 19 * 
 20 * You should have received a copy of the GNU Lesser General Public
 21 * License along with this library; if not, write to the Free Software
 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 23 * 
 24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 25 * $/LicenseInfo$
 26 */
 27
 28
 29#include "llviewerprecompiledheaders.h"
 30#include "llsecapi.h"
 31#include "llsechandler_basic.h"
 32#include <openssl/evp.h>
 33#include <openssl/err.h>
 34#include <map>
 35#include "llhttpclient.h"
 36
 37
 38
 39std::map<std::string, LLPointer<LLSecAPIHandler> > gHandlerMap;
 40LLPointer<LLSecAPIHandler> gSecAPIHandler;
 41
 42void initializeSecHandler()
 43{
 44	ERR_load_crypto_strings();
 45	OpenSSL_add_all_algorithms();
 46
 47	gHandlerMap[BASIC_SECHANDLER] = new LLSecAPIBasicHandler();
 48	
 49	
 50	// Currently, we only have the Basic handler, so we can point the main sechandler
 51	// pointer to the basic handler.  Later, we'll create a wrapper handler that
 52	// selects the appropriate sechandler as needed, for instance choosing the
 53	// mac keyring handler, with fallback to the basic sechandler
 54	gSecAPIHandler = gHandlerMap[BASIC_SECHANDLER];
 55
 56	// initialize all SecAPIHandlers
 57	std::string exception_msg;
 58	std::map<std::string, LLPointer<LLSecAPIHandler> >::const_iterator itr;
 59	for(itr = gHandlerMap.begin(); itr != gHandlerMap.end(); ++itr)
 60	{
 61		LLPointer<LLSecAPIHandler> handler = (*itr).second;
 62		try 
 63		{
 64			handler->init();
 65		}
 66		catch (LLProtectedDataException e)
 67		{
 68			exception_msg = e.getMessage();
 69		}
 70	}
 71	if (!exception_msg.empty())  // an exception was thrown.
 72	{
 73		throw LLProtectedDataException(exception_msg.c_str());
 74	}
 75
 76}
 77// start using a given security api handler.  If the string is empty
 78// the default is used
 79LLPointer<LLSecAPIHandler> getSecHandler(const std::string& handler_type)
 80{
 81	if (gHandlerMap.find(handler_type) != gHandlerMap.end())
 82	{
 83		return gHandlerMap[handler_type];
 84	}
 85	else
 86	{
 87		return LLPointer<LLSecAPIHandler>(NULL);
 88	}
 89}
 90// register a handler
 91void registerSecHandler(const std::string& handler_type, 
 92						LLPointer<LLSecAPIHandler>& handler)
 93{
 94	gHandlerMap[handler_type] = handler;
 95}
 96
 97std::ostream& operator <<(std::ostream& s, const LLCredential& cred)
 98{
 99	return s << (std::string)cred;
100}
101
102	
103// secapiSSLCertVerifyCallback
104// basic callback called when a cert verification is requested.
105// calls SECAPI to validate the context
106// not initialized in the above initialization function, due to unit tests
107// see llappviewer
108
109int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param)
110{
111	LLURLRequest *req = (LLURLRequest *)param;
112	LLPointer<LLCertificateStore> store = gSecAPIHandler->getCertificateStore("");
113	LLPointer<LLCertificateChain> chain = gSecAPIHandler->getCertificateChain(ctx);
114	LLSD validation_params = LLSD::emptyMap();
115	LLURI uri(req->getURL());
116	validation_params[CERT_HOSTNAME] = uri.hostName();
117	try
118	{
119		// we rely on libcurl to validate the hostname, as libcurl does more extensive validation
120		// leaving our hostname validation call mechanism for future additions with respect to
121		// OS native (Mac keyring, windows CAPI) validation.
122		store->validate(VALIDATION_POLICY_SSL & (~VALIDATION_POLICY_HOSTNAME), chain, validation_params);
123	}
124	catch (LLCertValidationTrustException& cert_exception)
125	{
126		LL_WARNS("AppInit") << "Cert not trusted: " << cert_exception.getMessage() << LL_ENDL;
127		return 0;		
128	}
129	catch (LLCertException& cert_exception)
130	{
131		LL_WARNS("AppInit") << "cert error " << cert_exception.getMessage() << LL_ENDL;
132		return 0;
133	}
134	catch (...)
135	{
136		LL_WARNS("AppInit") << "cert error " << LL_ENDL;
137		return 0;
138	}
139	return 1;
140}
141
142LLSD LLCredential::getLoginParams()
143{
144	LLSD result = LLSD::emptyMap();
145	try 
146	{
147		if (mIdentifier["type"].asString() == "agent")
148		{
149			// legacy credential
150			result["passwd"] = "$1$" + mAuthenticator["secret"].asString();
151			result["first"] = mIdentifier["first_name"];
152			result["last"] = mIdentifier["last_name"];
153		
154		}
155		else if (mIdentifier["type"].asString() == "account")
156		{
157			result["username"] = mIdentifier["account_name"];
158			result["passwd"] = mAuthenticator["secret"];
159										
160		}
161	}
162	catch (...)
163	{
164		// we could have corrupt data, so simply return a null login param if so
165		LL_WARNS("AppInit") << "Invalid credential" << LL_ENDL;
166	}
167	return result;
168}
169
170void LLCredential::identifierType(std::string &idType)
171{
172	if(mIdentifier.has("type"))
173	{
174		idType = mIdentifier["type"].asString();
175	}
176	else {
177		idType = std::string();
178		
179	}
180}
181
182void LLCredential::authenticatorType(std::string &idType)
183{
184	if(mAuthenticator.has("type"))
185	{
186		idType = mAuthenticator["type"].asString();
187	}
188	else {
189		idType = std::string();
190		
191	}
192}