diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/lluserauth.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/lluserauth.cpp')
-rw-r--r-- | linden/indra/newview/lluserauth.cpp | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/linden/indra/newview/lluserauth.cpp b/linden/indra/newview/lluserauth.cpp new file mode 100644 index 0000000..f980aa0 --- /dev/null +++ b/linden/indra/newview/lluserauth.cpp | |||
@@ -0,0 +1,354 @@ | |||
1 | /** | ||
2 | * @file lluserauth.cpp | ||
3 | * @brief LLUserAuth class implementation | ||
4 | * | ||
5 | * Copyright (c) 2003-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #include "lluserauth.h" | ||
31 | |||
32 | #include <sstream> | ||
33 | #include <iterator> | ||
34 | |||
35 | #include "lldir.h" | ||
36 | #include "llversion.h" | ||
37 | #include "llviewerbuild.h" | ||
38 | #include "llviewercontrol.h" | ||
39 | #include "llxmlrpctransaction.h" | ||
40 | |||
41 | // NOTE: MUST include these after otherincludes since queue gets redefined!?!! | ||
42 | #include <curl/curl.h> | ||
43 | #include <xmlrpc-epi/xmlrpc.h> | ||
44 | |||
45 | |||
46 | |||
47 | // Don't define PLATFORM_STRING for unknown platforms - they need | ||
48 | // to get added to the login cgi script, so we want this to cause an | ||
49 | // error if we get compiled for a different platform. | ||
50 | // *FIX: This is misreporting on linux. Change this so that linux is | ||
51 | // in fact reporting linux. | ||
52 | #if LL_WINDOWS || LL_LINUX | ||
53 | static const char* PLATFORM_STRING = "Win"; | ||
54 | #elif LL_DARWIN | ||
55 | static const char* PLATFORM_STRING = "Mac"; | ||
56 | #elif LL_LINUX | ||
57 | static const char* PLATFORM_STRING = "Lnx"; | ||
58 | #else | ||
59 | #error("Unknown platform defined!") | ||
60 | #endif | ||
61 | |||
62 | LLUserAuth *gUserAuthp = NULL; | ||
63 | |||
64 | |||
65 | LLUserAuth::LLUserAuth() : | ||
66 | mTransaction(NULL), | ||
67 | mLastTransferRateBPS(0) | ||
68 | { | ||
69 | mAuthResponse = E_NO_RESPONSE_YET; | ||
70 | } | ||
71 | |||
72 | LLUserAuth::~LLUserAuth() | ||
73 | { | ||
74 | delete mTransaction; | ||
75 | mTransaction = NULL; | ||
76 | } | ||
77 | |||
78 | // passwd is already MD5 hashed by the time we get to it. | ||
79 | void LLUserAuth::authenticate( | ||
80 | const char* auth_uri, | ||
81 | const char* method, | ||
82 | const char* firstname, | ||
83 | const char* lastname, | ||
84 | const char* passwd, | ||
85 | const char* start, | ||
86 | BOOL skip_optional, | ||
87 | BOOL accept_tos, | ||
88 | BOOL accept_critical_message, | ||
89 | const LLUUID& viewer_digest, | ||
90 | BOOL last_exec_froze, | ||
91 | const std::vector<const char*>& requested_options, | ||
92 | const std::string& hashed_mac, | ||
93 | const std::string& hashed_volume_serial) | ||
94 | { | ||
95 | std::string dpasswd("$1$"); | ||
96 | dpasswd.append(passwd); | ||
97 | llinfos << "Authenticating: " << firstname << " " << lastname << ", " | ||
98 | << /*dpasswd.c_str() <<*/ llendl; | ||
99 | std::ostringstream option_str; | ||
100 | option_str << "Options: "; | ||
101 | std::ostream_iterator<const char*> appender(option_str, ", "); | ||
102 | std::copy(requested_options.begin(), requested_options.end(), appender); | ||
103 | option_str << "END"; | ||
104 | llinfos << option_str.str().c_str() << llendl; | ||
105 | |||
106 | mAuthResponse = E_NO_RESPONSE_YET; | ||
107 | //mDownloadTimer.reset(); | ||
108 | |||
109 | // create the request | ||
110 | XMLRPC_REQUEST request = XMLRPC_RequestNew(); | ||
111 | XMLRPC_RequestSetMethodName(request, method); | ||
112 | XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); | ||
113 | |||
114 | // stuff the parameters | ||
115 | XMLRPC_VALUE params = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); | ||
116 | XMLRPC_VectorAppendString(params, "first", firstname, 0); | ||
117 | XMLRPC_VectorAppendString(params, "last", lastname, 0); | ||
118 | XMLRPC_VectorAppendString(params, "passwd", dpasswd.c_str(), 0); | ||
119 | XMLRPC_VectorAppendString(params, "start", start, 0); | ||
120 | char buffer[MAX_STRING]; | ||
121 | sprintf(buffer, "%d", LL_VERSION_MAJOR); | ||
122 | XMLRPC_VectorAppendString(params, "major", buffer, 0); | ||
123 | sprintf(buffer, "%d", LL_VERSION_MINOR); | ||
124 | XMLRPC_VectorAppendString(params, "minor", buffer, 0); | ||
125 | sprintf(buffer, "%d", LL_VERSION_PATCH); | ||
126 | XMLRPC_VectorAppendString(params, "patch", buffer, 0); | ||
127 | sprintf(buffer, "%d", LL_VIEWER_BUILD); | ||
128 | XMLRPC_VectorAppendString(params, "build", buffer, 0); | ||
129 | XMLRPC_VectorAppendString(params, "platform", PLATFORM_STRING, 0); | ||
130 | XMLRPC_VectorAppendString(params, "mac", hashed_mac.c_str(), 0); | ||
131 | // A bit of security through obscurity: id0 is volume_serial | ||
132 | XMLRPC_VectorAppendString(params, "id0", hashed_volume_serial.c_str(), 0); | ||
133 | if (skip_optional) | ||
134 | { | ||
135 | XMLRPC_VectorAppendString(params, "skipoptional", "true", 0); | ||
136 | } | ||
137 | if (accept_tos) | ||
138 | { | ||
139 | XMLRPC_VectorAppendString(params, "agree_to_tos", "true", 0); | ||
140 | } | ||
141 | if (accept_critical_message) | ||
142 | { | ||
143 | XMLRPC_VectorAppendString(params, "read_critical", "true", 0); | ||
144 | } | ||
145 | viewer_digest.toString(buffer); | ||
146 | XMLRPC_VectorAppendString(params, "viewer_digest", buffer, 0); | ||
147 | if (last_exec_froze) | ||
148 | { | ||
149 | XMLRPC_VectorAppendString(params, "last_exec_froze", "true", 0); | ||
150 | } | ||
151 | |||
152 | // append optional requests in an array | ||
153 | XMLRPC_VALUE options = XMLRPC_CreateVector("options", xmlrpc_vector_array); | ||
154 | std::vector<const char*>::const_iterator it = requested_options.begin(); | ||
155 | std::vector<const char*>::const_iterator end = requested_options.end(); | ||
156 | for( ; it < end; ++it) | ||
157 | { | ||
158 | XMLRPC_VectorAppendString(options, NULL, (*it), 0); | ||
159 | } | ||
160 | XMLRPC_AddValueToVector(params, options); | ||
161 | |||
162 | // put the parameters on the request | ||
163 | XMLRPC_RequestSetData(request, params); | ||
164 | |||
165 | mTransaction = new LLXMLRPCTransaction(auth_uri, request); | ||
166 | |||
167 | XMLRPC_RequestFree(request, 1); | ||
168 | |||
169 | llinfos << "LLUserAuth::authenticate: uri=" << auth_uri << llendl; | ||
170 | } | ||
171 | |||
172 | LLUserAuth::UserAuthcode LLUserAuth::authResponse() | ||
173 | { | ||
174 | if (!mTransaction) | ||
175 | { | ||
176 | return mAuthResponse; | ||
177 | } | ||
178 | |||
179 | bool done = mTransaction->process(); | ||
180 | |||
181 | if (!done) { | ||
182 | if (LLXMLRPCTransaction::StatusDownloading == mTransaction->status(0)) | ||
183 | { | ||
184 | mAuthResponse = E_DOWNLOADING; | ||
185 | } | ||
186 | |||
187 | return mAuthResponse; | ||
188 | } | ||
189 | |||
190 | |||
191 | mLastTransferRateBPS = mTransaction->transferRate(); | ||
192 | |||
193 | int result; | ||
194 | mTransaction->status(&result); | ||
195 | mErrorMessage = mTransaction->statusMessage(); | ||
196 | |||
197 | // if curl was ok, parse the download area. | ||
198 | switch (result) | ||
199 | { | ||
200 | case CURLE_OK: | ||
201 | mAuthResponse = parseResponse(); | ||
202 | break; | ||
203 | case CURLE_COULDNT_RESOLVE_HOST: | ||
204 | mAuthResponse = E_COULDNT_RESOLVE_HOST; | ||
205 | break; | ||
206 | case CURLE_SSL_PEER_CERTIFICATE: | ||
207 | mAuthResponse = E_SSL_PEER_CERTIFICATE; | ||
208 | break; | ||
209 | case CURLE_SSL_CACERT: | ||
210 | mAuthResponse = E_SSL_CACERT; | ||
211 | break; | ||
212 | case CURLE_SSL_CONNECT_ERROR: | ||
213 | mAuthResponse = E_SSL_CONNECT_ERROR; | ||
214 | break; | ||
215 | default: | ||
216 | mAuthResponse = E_UNHANDLED_ERROR; | ||
217 | break; | ||
218 | } | ||
219 | |||
220 | llinfos << "Processed response: " << result << llendl; | ||
221 | |||
222 | delete mTransaction; | ||
223 | mTransaction = NULL; | ||
224 | |||
225 | return mAuthResponse; | ||
226 | } | ||
227 | |||
228 | static void parseOptionInto( | ||
229 | const std::string& id, XMLRPC_VALUE option, LLUserAuth::options_t& options) | ||
230 | { | ||
231 | std::string key; | ||
232 | std::string val; | ||
233 | char buffer[MAX_STRING]; | ||
234 | XMLRPC_VALUE_TYPE_EASY type; | ||
235 | XMLRPC_VALUE row = XMLRPC_VectorRewind(option); | ||
236 | while(row) | ||
237 | { | ||
238 | XMLRPC_VALUE opt = XMLRPC_VectorRewind(row); | ||
239 | LLUserAuth::response_t responses; | ||
240 | while(opt) | ||
241 | { | ||
242 | key.assign(XMLRPC_GetValueID(opt)); | ||
243 | //llinfos "option key: " << key << llendl; | ||
244 | type = XMLRPC_GetValueTypeEasy(opt); | ||
245 | if(xmlrpc_type_string == type) | ||
246 | { | ||
247 | val.assign(XMLRPC_GetValueString(opt)); | ||
248 | } | ||
249 | else if(xmlrpc_type_int == type) | ||
250 | { | ||
251 | sprintf(buffer, "%d", XMLRPC_GetValueInt(opt)); | ||
252 | val.assign(buffer); | ||
253 | } | ||
254 | //llinfos "option val: " << val << llendl; | ||
255 | responses.insert(LLUserAuth::response_t::value_type(key, val)); | ||
256 | opt = XMLRPC_VectorNext(row); | ||
257 | } | ||
258 | options.push_back(responses); | ||
259 | row = XMLRPC_VectorNext(option); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | LLUserAuth::UserAuthcode LLUserAuth::parseResponse() | ||
264 | { | ||
265 | // The job of this function is to parse sCurlDownloadArea and | ||
266 | // extract every member into either the mResponses or | ||
267 | // mOptions. For now, we will only be looking at mResponses, which | ||
268 | // will all be string => string pairs. | ||
269 | UserAuthcode rv = E_UNHANDLED_ERROR; | ||
270 | XMLRPC_REQUEST response = mTransaction->response(); | ||
271 | if(!response) return rv; | ||
272 | |||
273 | // clear out any old parsing | ||
274 | mResponses.clear(); | ||
275 | mOptions.clear(); | ||
276 | |||
277 | // Now, parse everything | ||
278 | std::string key; | ||
279 | std::string val; | ||
280 | XMLRPC_VALUE param = NULL; | ||
281 | XMLRPC_VALUE current = NULL; | ||
282 | XMLRPC_VALUE_TYPE_EASY type; | ||
283 | param = XMLRPC_RequestGetData(response); | ||
284 | if(!param) goto exit; | ||
285 | current = XMLRPC_VectorRewind(param); | ||
286 | while(current) | ||
287 | { | ||
288 | key.assign(XMLRPC_GetValueID(current)); | ||
289 | lldebugs << "key: " << key << llendl; | ||
290 | type = XMLRPC_GetValueTypeEasy(current); | ||
291 | if(xmlrpc_type_string == type) | ||
292 | { | ||
293 | val.assign(XMLRPC_GetValueString(current)); | ||
294 | lldebugs << "val: " << val << llendl; | ||
295 | mResponses.insert(response_t::value_type(key, val)); | ||
296 | } | ||
297 | else if(xmlrpc_type_int == type) | ||
298 | { | ||
299 | char buf[MAX_STRING]; | ||
300 | snprintf(buf, MAX_STRING, "%d", XMLRPC_GetValueInt(current)); | ||
301 | val.assign(buf); | ||
302 | lldebugs << "val: " << val << llendl; | ||
303 | mResponses.insert(response_t::value_type(key, val)); | ||
304 | } | ||
305 | else if(xmlrpc_type_array == type) | ||
306 | { | ||
307 | options_t options; | ||
308 | parseOptionInto(key, current, options); | ||
309 | mOptions.insert(all_options_t::value_type(key, options)); | ||
310 | } | ||
311 | else | ||
312 | { | ||
313 | // whoops - bad response | ||
314 | llwarns << "Unhandled xmlrpc type, key, value: " << type << " " | ||
315 | << key << " " << val << "." << llendl; | ||
316 | rv = E_UNHANDLED_ERROR; | ||
317 | break; | ||
318 | } | ||
319 | current = XMLRPC_VectorNext(param); | ||
320 | rv = E_OK; | ||
321 | } | ||
322 | |||
323 | exit: | ||
324 | return rv; | ||
325 | } | ||
326 | |||
327 | const char* LLUserAuth::getResponse(const char* name) const | ||
328 | { | ||
329 | if(!name) return NULL; | ||
330 | std::string key(name); | ||
331 | response_t::const_iterator it = mResponses.find(key); | ||
332 | if(it != mResponses.end()) | ||
333 | { | ||
334 | return((*it).second.c_str()); | ||
335 | } | ||
336 | return NULL; | ||
337 | } | ||
338 | |||
339 | BOOL LLUserAuth::getOptions(const char* name, options_t& options) const | ||
340 | { | ||
341 | if(!name) return FALSE; | ||
342 | std::string key(name); | ||
343 | all_options_t::const_iterator it = mOptions.find(key); | ||
344 | if(it != mOptions.end()) | ||
345 | { | ||
346 | // found the option set, copyt them onto the container. | ||
347 | std::back_insert_iterator<options_t> ii(options); | ||
348 | std::copy((*it).second.begin(), (*it).second.end(), ii); | ||
349 | return TRUE; | ||
350 | } | ||
351 | return FALSE; | ||
352 | } | ||
353 | |||
354 | |||