aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lluserauth.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/lluserauth.cpp
parentREADME.txt (diff)
downloadmeta-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.cpp354
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
53static const char* PLATFORM_STRING = "Win";
54#elif LL_DARWIN
55static const char* PLATFORM_STRING = "Mac";
56#elif LL_LINUX
57static const char* PLATFORM_STRING = "Lnx";
58#else
59#error("Unknown platform defined!")
60#endif
61
62LLUserAuth *gUserAuthp = NULL;
63
64
65LLUserAuth::LLUserAuth() :
66 mTransaction(NULL),
67 mLastTransferRateBPS(0)
68{
69 mAuthResponse = E_NO_RESPONSE_YET;
70}
71
72LLUserAuth::~LLUserAuth()
73{
74 delete mTransaction;
75 mTransaction = NULL;
76}
77
78// passwd is already MD5 hashed by the time we get to it.
79void 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
172LLUserAuth::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
228static 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
263LLUserAuth::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
327const 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
339BOOL 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