diff options
| -rw-r--r-- | indra/llplugin/llplugincookiestore.cpp | 73 | ||||
| -rw-r--r-- | indra/llplugin/llplugincookiestore.h | 9 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/llviewermedia.cpp | 99 | ||||
| -rw-r--r-- | indra/newview/llviewermedia.h | 8 | 
5 files changed, 184 insertions, 12 deletions
| diff --git a/indra/llplugin/llplugincookiestore.cpp b/indra/llplugin/llplugincookiestore.cpp index 1964b8d789..92ee24e1d5 100644 --- a/indra/llplugin/llplugincookiestore.cpp +++ b/indra/llplugin/llplugincookiestore.cpp @@ -62,11 +62,11 @@ LLPluginCookieStore::Cookie::Cookie(const std::string &s, std::string::size_type  {  } -LLPluginCookieStore::Cookie *LLPluginCookieStore::Cookie::createFromString(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end) +LLPluginCookieStore::Cookie *LLPluginCookieStore::Cookie::createFromString(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, const std::string &host)  {  	Cookie *result = new Cookie(s, cookie_start, cookie_end); -	if(!result->parse()) +	if(!result->parse(host))  	{  		delete result;  		result = NULL; @@ -92,7 +92,7 @@ std::string LLPluginCookieStore::Cookie::getKey() const  	return result;  } -bool LLPluginCookieStore::Cookie::parse() +bool LLPluginCookieStore::Cookie::parse(const std::string &host)  {  	bool first_field = true; @@ -248,7 +248,50 @@ bool LLPluginCookieStore::Cookie::parse()  	// The cookie MUST have a name  	if(mNameEnd <= mNameStart)  		return false; +	 +	// If the cookie doesn't have a domain, add the current host as the domain. +	if(mDomainEnd <= mDomainStart) +	{ +		if(host.empty()) +		{ +			// no domain and no current host -- this is a parse failure. +			return false; +		} +		 +		// Figure out whether this cookie ended with a ";" or not... +		std::string::size_type last_char = mCookie.find_last_not_of(" "); +		if((last_char != std::string::npos) && (mCookie[last_char] != ';')) +		{ +			mCookie += ";"; +		} +		 +		mCookie += " domain="; +		mDomainStart = mCookie.size(); +		mCookie += host; +		mDomainEnd = mCookie.size(); +		 +		lldebugs << "added domain (" << mDomainStart << " to " << mDomainEnd << "), new cookie is: " << mCookie << llendl; +	} + +	// If the cookie doesn't have a path, add "/". +	if(mPathEnd <= mPathStart) +	{ +		// Figure out whether this cookie ended with a ";" or not... +		std::string::size_type last_char = mCookie.find_last_not_of(" "); +		if((last_char != std::string::npos) && (mCookie[last_char] != ';')) +		{ +			mCookie += ";"; +		} +		 +		mCookie += " path="; +		mPathStart = mCookie.size(); +		mCookie += "/"; +		mPathEnd = mCookie.size(); +		lldebugs << "added path (" << mPathStart << " to " << mPathEnd << "), new cookie is: " << mCookie << llendl; +	} +	 +	  	return true;  } @@ -409,13 +452,29 @@ void LLPluginCookieStore::setCookies(const std::string &cookies, bool mark_chang  	while(start != std::string::npos)  	{ -		std::string::size_type end = cookies.find('\n', start); +		std::string::size_type end = cookies.find_first_of("\r\n", start);  		if(end > start)  		{  			// The line is non-empty.  Try to create a cookie from it.  			setOneCookie(cookies, start, end, mark_changed);  		} -		start = cookies.find_first_not_of("\n ", end); +		start = cookies.find_first_not_of("\r\n ", end); +	} +} + +void LLPluginCookieStore::setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed) +{ +	std::string::size_type start = 0; + +	while(start != std::string::npos) +	{ +		std::string::size_type end = cookies.find_first_of("\r\n", start); +		if(end > start) +		{ +			// The line is non-empty.  Try to create a cookie from it. +			setOneCookie(cookies, start, end, mark_changed, host); +		} +		start = cookies.find_first_not_of("\r\n ", end);  	}  } @@ -502,9 +561,9 @@ std::string LLPluginCookieStore::unquoteString(const std::string &s)  // When deleting with mark_changed set to true, this replaces the existing cookie in the list with an entry that's marked both dead and changed.  // Some time later when writeChangedCookies() is called with clear_changed set to true, the dead cookie is deleted from the list after being returned, so that the  // delete operation (in the form of the expired cookie) is passed along. -void LLPluginCookieStore::setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed) +void LLPluginCookieStore::setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed, const std::string &host)  { -	Cookie *cookie = Cookie::createFromString(s, cookie_start, cookie_end); +	Cookie *cookie = Cookie::createFromString(s, cookie_start, cookie_end, host);  	if(cookie)  	{  		lldebugs << "setting cookie: " << cookie->getCookie() << llendl; diff --git a/indra/llplugin/llplugincookiestore.h b/indra/llplugin/llplugincookiestore.h index 5250f008b6..a93f0c14f0 100644 --- a/indra/llplugin/llplugincookiestore.h +++ b/indra/llplugin/llplugincookiestore.h @@ -66,18 +66,21 @@ public:  	void setCookies(const std::string &cookies, bool mark_changed = true);  	void readCookies(std::istream& s, bool mark_changed = true); +	// sets one or more cookies (without reinitializing anything), supplying a hostname the cookies came from -- use when setting a cookie manually +	void setCookiesFromHost(const std::string &cookies, const std::string &host, bool mark_changed = true); +  	// quote or unquote a string as per the definition of 'quoted-string' in rfc2616  	static std::string quoteString(const std::string &s);  	static std::string unquoteString(const std::string &s);  private: -	void setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed); +	void setOneCookie(const std::string &s, std::string::size_type cookie_start, std::string::size_type cookie_end, bool mark_changed, const std::string &host = LLStringUtil::null);  	class Cookie  	{  	public: -		static Cookie *createFromString(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos); +		static Cookie *createFromString(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos, const std::string &host = LLStringUtil::null);  		// Construct a string from the cookie that uniquely represents it, to be used as a key in a std::map.  		std::string getKey() const; @@ -95,7 +98,7 @@ private:  	private:  		Cookie(const std::string &s, std::string::size_type cookie_start = 0, std::string::size_type cookie_end = std::string::npos); -		bool parse(); +		bool parse(const std::string &host);  		std::string::size_type findFieldEnd(std::string::size_type start = 0, std::string::size_type end = std::string::npos);  		bool matchName(std::string::size_type start, std::string::size_type end, const char *name); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 1a1dffe85c..b5a73a3143 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -3087,6 +3087,13 @@ bool process_login_success_response()  		}  	} +	// Start the process of fetching the OpenID session cookie for this user login +	std::string openid_url = response["openid_url"]; +	if(!openid_url.empty()) +	{ +		std::string openid_token = response["openid_token"]; +		LLViewerMedia::openIDSetup(openid_url, openid_token); +	}  	bool success = false;  	// JC: gesture loading done below, when we have an asset system diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 6f0d9cdd95..d9fabc7d64 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -257,7 +257,43 @@ public:  		LLViewerMediaImpl *mMediaImpl;  		bool mInitialized;  }; + +class LLViewerMediaOpenIDResponder : public LLHTTPClient::Responder +{ +LOG_CLASS(LLViewerMediaOpenIDResponder); +public: +	LLViewerMediaOpenIDResponder( ) +	{ +	} + +	~LLViewerMediaOpenIDResponder() +	{ +	} + +	/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content) +	{ +		LL_DEBUGS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL; +		LL_DEBUGS("MediaAuth") << content << LL_ENDL; +		std::string cookie = content["set-cookie"].asString(); +		 +		LLViewerMedia::openIDCookieResponse(cookie); +	} + +	/* virtual */ void completedRaw( +		U32 status, +		const std::string& reason, +		const LLChannelDescriptors& channels, +		const LLIOPipe::buffer_ptr_t& buffer) +	{ +		// This is just here to disable the default behavior (attempting to parse the response as llsd). +		// We don't care about the content of the response, only the set-cookie header. +	} + +}; +  LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL; +LLURL LLViewerMedia::sOpenIDURL; +std::string LLViewerMedia::sOpenIDCookie;  static LLViewerMedia::impl_list sViewerMediaImplList;  static LLViewerMedia::impl_id_map sViewerMediaTextureIDMap;  static LLTimer sMediaCreateTimer; @@ -1067,7 +1103,8 @@ void LLViewerMedia::clearAllCookies()  		}  	} -	 +	// If we have an OpenID cookie, re-add it to the cookie store. +	setOpenIDCookie();  }  ///////////////////////////////////////////////////////////////////////////////////////// @@ -1168,7 +1205,9 @@ void LLViewerMedia::loadCookieFile()  			pimpl->mMediaSource->clear_cookies();  		}  	} - +	 +	// If we have an OpenID cookie, re-add it to the cookie store. +	setOpenIDCookie();  } @@ -1241,6 +1280,62 @@ void LLViewerMedia::removeCookie(const std::string &name, const std::string &dom  } +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setOpenIDCookie() +{ +	if(!sOpenIDCookie.empty()) +	{ +		getCookieStore()->setCookiesFromHost(sOpenIDCookie, sOpenIDURL.mAuthority); +	} +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string &openid_token) +{ +	LL_DEBUGS("MediaAuth") << "url = \"" << openid_url << "\", token = \"" << openid_token << "\"" << LL_ENDL; + +	// post the token to the url  +	// the responder will need to extract the cookie(s). + +	// Save the OpenID URL for later -- we may need the host when adding the cookie. +	sOpenIDURL.init(openid_url.c_str()); +	 +	// We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies. +	sOpenIDCookie.clear(); + +	LLSD headers = LLSD::emptyMap(); +	// Keep LLHTTPClient from adding an "Accept: application/llsd+xml" header +	headers["Accept"] = "*/*"; +	// and use the expected content-type for a post, instead of the LLHTTPClient::postRaw() default of "application/octet-stream" +	headers["Content-Type"] = "application/x-www-form-urlencoded"; + +	// postRaw() takes ownership of the buffer and releases it later, so we need to allocate a new buffer here. +	size_t size = openid_token.size(); +	U8 *data = new U8[size]; +	memcpy(data, openid_token.data(), size); + +	LLHTTPClient::postRaw(  +		openid_url,  +		data,  +		size,  +		new LLViewerMediaOpenIDResponder(), +		headers); +			 +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::openIDCookieResponse(const std::string &cookie) +{ +	LL_DEBUGS("MediaAuth") << "Cookie received: \"" << cookie << "\"" << LL_ENDL; +	 +	sOpenIDCookie += cookie; + +	setOpenIDCookie(); +} +  bool LLViewerMedia::hasInWorldMedia()  {  	if (sInWorldMediaDisabled) return false; diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 10dacf9532..e829d7a5b4 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -44,6 +44,8 @@  #include "llpluginclassmedia.h"  #include "v4color.h" +#include "llurl.h" +  class LLViewerMediaImpl;  class LLUUID;  class LLViewerMediaTexture; @@ -152,11 +154,17 @@ public:  	static void addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path = std::string("/"), bool secure = false );  	static void addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path = std::string("/"), bool secure = false );  	static void removeCookie(const std::string &name, const std::string &domain, const std::string &path = std::string("/") ); + +	static void openIDSetup(const std::string &openid_url, const std::string &openid_token); +	static void openIDCookieResponse(const std::string &cookie);  private: +	static void setOpenIDCookie();  	static void onTeleportFinished();  	static LLPluginCookieStore *sCookieStore; +	static LLURL sOpenIDURL; +	static std::string sOpenIDCookie;  };  // Implementation functions not exported into header file | 
