XMLRPC_VALUE xsm_system_multicall_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { XMLRPC_VALUE xArray = XMLRPC_VectorRewind(XMLRPC_RequestGetData(input)); XMLRPC_VALUE xReturn = XMLRPC_CreateVector(0, xmlrpc_vector_array); if (xArray) { XMLRPC_VALUE xMethodIter = XMLRPC_VectorRewind(xArray); while (xMethodIter) { XMLRPC_REQUEST request = XMLRPC_RequestNew(); if(request) { const char* methodName = XMLRPC_VectorGetStringWithID(xMethodIter, "methodName"); XMLRPC_VALUE params = XMLRPC_VectorGetValueWithID(xMethodIter, "params"); if(methodName && params) { XMLRPC_VALUE xRandomArray = XMLRPC_CreateVector(0, xmlrpc_vector_array); XMLRPC_RequestSetMethodName(request, methodName); XMLRPC_RequestSetData(request, params); XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); XMLRPC_AddValueToVector(xRandomArray, XMLRPC_ServerCallMethod(server, request, userData)); XMLRPC_AddValueToVector(xReturn, xRandomArray); } XMLRPC_RequestFree(request, 1); } xMethodIter = XMLRPC_VectorNext(xArray); } } return xReturn; }
/* this complies with system.methodSignature as defined at * http://xmlrpc.usefulinc.com/doc/sysmethodsig.html */ static XMLRPC_VALUE xi_system_method_signature_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { const char* method = XMLRPC_GetValueString(XMLRPC_VectorRewind(XMLRPC_RequestGetData(input))); XMLRPC_VALUE xResponse = NULL; /* lazy loading of introspection data */ check_docs_loaded(server, userData); if(method) { server_method* sm = find_method(server, method); if(sm && sm->desc) { XMLRPC_VALUE xTypesArray = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); XMLRPC_VALUE xIter, xParams, xSig, xSigIter; const char* type; /* array of possible signatures. */ xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_array); /* find first signature */ xSig = XMLRPC_VectorGetValueWithID(sm->desc, xi_token_signatures); xSigIter = XMLRPC_VectorRewind( xSig ); /* iterate through sigs */ while(xSigIter) { /* first type is the return value */ type = XMLRPC_VectorGetStringWithID(XMLRPC_VectorRewind( XMLRPC_VectorGetValueWithID(xSigIter, xi_token_returns)), xi_token_type); XMLRPC_AddValueToVector(xTypesArray, XMLRPC_CreateValueString(NULL, type ? type : type_to_str(xmlrpc_none, 0), 0)); /* the rest are parameters */ xParams = XMLRPC_VectorGetValueWithID(xSigIter, xi_token_params); xIter = XMLRPC_VectorRewind(xParams); /* iter through params, adding to types array */ while(xIter) { XMLRPC_AddValueToVector(xTypesArray, XMLRPC_CreateValueString(NULL, XMLRPC_VectorGetStringWithID(xIter, xi_token_type), 0)); xIter = XMLRPC_VectorNext(xParams); } /* add types for this signature */ XMLRPC_AddValueToVector(xResponse, xTypesArray); xSigIter = XMLRPC_VectorNext( xSig ); } } } return xResponse; }
/****f* SERVER/XMLRPC_ServerAddIntrospectionData * NAME * XMLRPC_ServerAddIntrospectionData * SYNOPSIS * int XMLRPC_ServerAddIntrospectionData(XMLRPC_SERVER server, XMLRPC_VALUE desc) * FUNCTION * updates server with additional introspection data * INPUTS * server - target server * desc - introspection data, should be a struct generated by * XMLRPC_IntrospectionCreateDescription () * RESULT * int - 1 if success, else 0 * NOTES * - function will fail if neither typeList nor methodList key is present in struct. * - if method or type already exists, it will be replaced. * - desc is never freed by the server. caller is responsible for cleanup. * BUGS * - horribly slow lookups. prime candidate for hash improvements. * - uglier and more complex than I like to see for API functions. * SEE ALSO * XMLRPC_ServerAddIntrospectionData () * XMLRPC_ServerRegisterIntrospectionCallback () * XMLRPC_CleanupValue () * SOURCE */ int XMLRPC_ServerAddIntrospectionData(XMLRPC_SERVER server, XMLRPC_VALUE desc) { int bSuccess = 0; if(server && desc) { XMLRPC_VALUE xNewTypes = XMLRPC_VectorGetValueWithID(desc, "typeList"); XMLRPC_VALUE xNewMethods = XMLRPC_VectorGetValueWithID(desc, "methodList"); XMLRPC_VALUE xServerTypes = XMLRPC_VectorGetValueWithID(server->xIntrospection, "typeList"); if(xNewMethods) { XMLRPC_VALUE xMethod = XMLRPC_VectorRewind(xNewMethods); while(xMethod) { const char* name = XMLRPC_VectorGetStringWithID(xMethod, xi_token_name); server_method* sm = find_method(server, name); if(sm) { if(sm->desc) { XMLRPC_CleanupValue(sm->desc); } sm->desc = XMLRPC_CopyValue(xMethod); bSuccess = 1; } xMethod = XMLRPC_VectorNext(xNewMethods); } } if(xNewTypes) { if(!xServerTypes) { if(!server->xIntrospection) { server->xIntrospection = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); } XMLRPC_AddValueToVector(server->xIntrospection, xNewTypes); bSuccess = 1; } else { XMLRPC_VALUE xIter = XMLRPC_VectorRewind(xNewTypes); while(xIter) { /* get rid of old values */ XMLRPC_VALUE xPrev = find_named_value(xServerTypes, XMLRPC_VectorGetStringWithID(xIter, xi_token_name)); if(xPrev) { XMLRPC_VectorRemoveValue(xServerTypes, xPrev); } XMLRPC_AddValueToVector(xServerTypes, xIter); bSuccess = 1; xIter = XMLRPC_VectorNext(xNewTypes); } } } } return bSuccess; }
/* system.describeMethods() callback */ static XMLRPC_VALUE xi_system_describe_methods_cb(XMLRPC_SERVER server, XMLRPC_REQUEST input, void* userData) { XMLRPC_VALUE xParams = XMLRPC_VectorRewind(XMLRPC_RequestGetData(input)); XMLRPC_VALUE xResponse = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); XMLRPC_VALUE xMethodList = XMLRPC_CreateVector("methodList", xmlrpc_vector_array); XMLRPC_VALUE xTypeList = NULL; int bAll = 1; /* lazy loading of introspection data */ check_docs_loaded(server, userData); xTypeList = XMLRPC_VectorGetValueWithID(server->xIntrospection, "typeList"); XMLRPC_AddValueToVector(xResponse, xTypeList); XMLRPC_AddValueToVector(xResponse, xMethodList); /* check if we have any param */ if(xParams) { /* check if string or vector (1 or n) */ XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(xParams); if(type == xmlrpc_string) { /* just one. spit it out. */ describe_method(server, xMethodList, XMLRPC_GetValueString(xParams)); bAll = 0; } else if(type == xmlrpc_vector) { /* multiple. spit all out */ XMLRPC_VALUE xIter = XMLRPC_VectorRewind(xParams); while(xIter) { describe_method(server, xMethodList, XMLRPC_GetValueString(xIter)); xIter = XMLRPC_VectorNext(xParams); } bAll = 0; } } /* otherwise, default to sending all methods */ if(bAll) { q_iter qi = Q_Iter_Head_F(&server->methodlist); while( qi ) { server_method* sm = Q_Iter_Get_F(qi); if(sm) { XMLRPC_AddValueToVector(xMethodList, sm->desc); } qi = Q_Iter_Next_F(qi); } } return xResponse; }
t_int XMLRPC::genericSDTSerialize(sourceType *_source) { return XMLRPC_AddValueToVector( XMLRPC_RequestGetData(xmlrpc_request), XMLRPC_CreateValueInt(NULL, static_cast<int>(*_source)) ); }
/* utility function for xi_system_describe_methods_cb */ static inline void describe_method(XMLRPC_SERVER server, XMLRPC_VALUE vector, const char* method) { if(method) { server_method* sm = find_method(server, method); if(sm) { XMLRPC_AddValueToVector(vector, sm->desc); } } }
bool XMLRPC::stringToBytes(const std::string* _source) { XMLRPC_AddValueToVector( XMLRPC_RequestGetData(xmlrpc_request), XMLRPC_CreateValueString(NULL, _source->c_str(), _source->size()) ); return true; }
bool XMLRPC::floatToBytes(const t_float* _source) { XMLRPC_AddValueToVector( XMLRPC_RequestGetData(xmlrpc_request), XMLRPC_CreateValueDouble(NULL, (*_source)) ); return true; }
bool XMLRPC::addByte(t_byte const _byte) { XMLRPC_AddValueToVector( XMLRPC_RequestGetData(xmlrpc_request), XMLRPC_CreateValueInt(NULL, _byte) ); success(); return true; }
bool XMLRPC::addBytes(t_byteCP _bytes, t_uint const _size) { t_uint size = _size; BTG_ICHECK( genericSDTSerialize<t_uint>(&size) ); if(size == 0) { return true; } XMLRPC_AddValueToVector( XMLRPC_RequestGetData(xmlrpc_request), XMLRPC_CreateValueBase64(NULL, reinterpret_cast<const char*>(_bytes), _size) ); return true; }
/* * This handler takes six parameters, and returns an array containing all the * parameters. */ XMLRPC_VALUE validator1_manyTypesTest (XMLRPC_SERVER server, XMLRPC_REQUEST xRequest, void* userData) { XMLRPC_VALUE xArray = XMLRPC_CreateVector(0, xmlrpc_vector_array); if(xRequest && xArray) { XMLRPC_VALUE xParams = XMLRPC_RequestGetData(xRequest); XMLRPC_VALUE xIter = XMLRPC_VectorRewind(xParams); while(xIter) { XMLRPC_AddValueToVector(xArray, XMLRPC_CopyValue(xIter)); xIter = XMLRPC_VectorNext(xParams); } } return xArray; }
bool XMLRPC::boolToBytes(bool const _source) { int val=0; if (_source) val=1; XMLRPC_AddValueToVector( XMLRPC_RequestGetData(xmlrpc_request), XMLRPC_CreateValueBoolean(NULL, val) ); success(); return true; }
/* describe a value (param, return, type) */ static XMLRPC_VALUE describeValue_worker(const char* type, const char* id, const char* desc, int optional, const char* default_val, XMLRPC_VALUE sub_params) { XMLRPC_VALUE xParam = NULL; if(id || desc) { xParam = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); XMLRPC_VectorAppendString(xParam, xi_token_name, id, 0); XMLRPC_VectorAppendString(xParam, xi_token_type, type, 0); XMLRPC_VectorAppendString(xParam, xi_token_description, desc, 0); if(optional != 2) { XMLRPC_VectorAppendInt(xParam, xi_token_optional, optional); } if(optional == 1 && default_val) { XMLRPC_VectorAppendString(xParam, xi_token_default, default_val, 0); } XMLRPC_AddValueToVector(xParam, sub_params); } return xParam; }
void XmlRpcCall::AddStringToArray(const std::string& name, const char *sstr) { // Does this kind array exist in current xmlrpc-call? std::map<std::string, XMLRPC_VALUE>::iterator iter = mapArrays_.find(name); if ( iter != mapArrays_.end()) { //There exist allready given array. Add string there. XMLRPC_VectorAppendString(iter->second, 0, sstr, 0); } else { // Create new array into xmlrpc-call. mapArrays_[name] = XMLRPC_CreateVector(name.c_str(), xmlrpc_vector_array); // Note here paramList owns created vector (assumption) and paramList is owned by request_ object. XMLRPC_AddValueToVector(paramList_, mapArrays_[name]); // Add string there. XMLRPC_VectorAppendString(mapArrays_[name], 0, sstr, 0); } }
void LLXMLRPCValue::appendDouble(double v) { XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueDouble(NULL, v)); }
void LLXMLRPCValue::appendBool(bool v) { XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueBoolean(NULL, v)); }
void LLXMLRPCValue::appendInt(int v) { XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueInt(NULL, v)); }
void LLUserAuth::authenticate( const std::string& auth_uri, const std::string& method, const std::string& firstname, const std::string& lastname, LLUUID web_login_key, const std::string& start, BOOL skip_optional, BOOL accept_tos, BOOL accept_critical_message, BOOL last_exec_froze, const std::vector<const char*>& requested_options, const std::string& hashed_mac, const std::string& hashed_volume_serial) { LL_INFOS2("AppInit", "Authentication") << "Authenticating: " << firstname << " " << lastname << ", " << /*dpasswd.c_str() <<*/ LL_ENDL; std::ostringstream option_str; option_str << "Options: "; std::ostream_iterator<const char*> appender(option_str, ", "); std::copy(requested_options.begin(), requested_options.end(), appender); option_str << "END"; LL_INFOS2("AppInit", "Authentication") << option_str.str() << LL_ENDL; mAuthResponse = E_NO_RESPONSE_YET; //mDownloadTimer.reset(); // create the request XMLRPC_REQUEST request = XMLRPC_RequestNew(); XMLRPC_RequestSetMethodName(request, method.c_str()); XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); // stuff the parameters XMLRPC_VALUE params = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); XMLRPC_VectorAppendString(params, "first", firstname.c_str(), 0); XMLRPC_VectorAppendString(params, "last", lastname.c_str(), 0); XMLRPC_VectorAppendString(params, "web_login_key", web_login_key.getString().c_str(), 0); XMLRPC_VectorAppendString(params, "start", start.c_str(), 0); XMLRPC_VectorAppendString(params, "version", gCurrentVersion.c_str(), 0); // Includes channel name XMLRPC_VectorAppendString(params, "channel", gVersionChannel, 0); XMLRPC_VectorAppendString(params, "platform", PLATFORM_STRING, 0); XMLRPC_VectorAppendString(params, "mac", hashed_mac.c_str(), 0); // A bit of security through obscurity: id0 is volume_serial XMLRPC_VectorAppendString(params, "id0", hashed_volume_serial.c_str(), 0); if (skip_optional) { XMLRPC_VectorAppendString(params, "skipoptional", "true", 0); } if (accept_tos) { XMLRPC_VectorAppendString(params, "agree_to_tos", "true", 0); } if (accept_critical_message) { XMLRPC_VectorAppendString(params, "read_critical", "true", 0); } XMLRPC_VectorAppendInt(params, "last_exec_event", (int) last_exec_froze); // append optional requests in an array XMLRPC_VALUE options = XMLRPC_CreateVector("options", xmlrpc_vector_array); std::vector<const char*>::const_iterator it = requested_options.begin(); std::vector<const char*>::const_iterator end = requested_options.end(); for( ; it < end; ++it) { XMLRPC_VectorAppendString(options, NULL, (*it), 0); } XMLRPC_AddValueToVector(params, options); // put the parameters on the request XMLRPC_RequestSetData(request, params); mResponder = new XMLRPCResponder; LLHTTPClient::postXMLRPC(auth_uri, request, mResponder); LL_INFOS2("AppInit", "Authentication") << "LLUserAuth::authenticate: uri=" << auth_uri << LL_ENDL; }
// passwd is already MD5 hashed by the time we get to it. void LLUserAuth::authenticate( const std::string& auth_uri, const std::string& method, const std::string& firstname, const std::string& lastname, const std::string& passwd, const std::string& start, BOOL skip_optional, BOOL accept_tos, BOOL accept_critical_message, BOOL last_exec_froze, const std::vector<const char*>& requested_options, const std::string& hashed_mac, const std::string& hashed_volume_serial) { std::string dpasswd("$1$"); dpasswd.append(passwd); LL_INFOS2("AppInit", "Authentication") << "Authenticating: " << firstname << " " << lastname << ", " << /*dpasswd.c_str() <<*/ LL_ENDL; std::ostringstream option_str; option_str << "Options: "; std::ostream_iterator<const char*> appender(option_str, ", "); std::copy(requested_options.begin(), requested_options.end(), appender); option_str << "END"; LL_INFOS2("AppInit", "Authentication") << option_str.str().c_str() << LL_ENDL; mAuthResponse = E_NO_RESPONSE_YET; //mDownloadTimer.reset(); // create the request XMLRPC_REQUEST request = XMLRPC_RequestNew(); XMLRPC_RequestSetMethodName(request, method.c_str()); XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); // stuff the parameters XMLRPC_VALUE params = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); XMLRPC_VectorAppendString(params, "first", firstname.c_str(), 0); XMLRPC_VectorAppendString(params, "last", lastname.c_str(), 0); XMLRPC_VectorAppendString(params, "passwd", dpasswd.c_str(), 0); XMLRPC_VectorAppendString(params, "start", start.c_str(), 0); XMLRPC_VectorAppendString(params, "version", llformat("%d.%d.%d.%d", gVersionMajor, gVersionMinor, gVersionPatch, gVersionBuild).c_str(), 0); // Singu Note: At the request of Linden Lab we change channel sent to the login server in the following way: // * If channel is "Replex" we change it to "Replex Release", due to their statistics system // not being able to distinguish just the release version // * We append "64" to channel name on 64-bit for systems for the LL stats system to be able to produce independent // crash statistics depending on the architecture std::string chan(gVersionChannel); if (chan == "Replex") { chan += " Release"; } #if defined(_WIN64) || defined(__x86_64__) chan += " 64"; #endif XMLRPC_VectorAppendString(params, "channel", chan.c_str(), 0); XMLRPC_VectorAppendString(params, "platform", PLATFORM_STRING, 0); XMLRPC_VectorAppendString(params, "mac", hashed_mac.c_str(), 0); // A bit of security through obscurity: id0 is volume_serial // ^^^^^^^^^^^^^^^^^^^^ // you f*****g idiot - charbl XMLRPC_VectorAppendString(params, "id0", hashed_volume_serial.c_str(), 0); if (skip_optional) { XMLRPC_VectorAppendString(params, "skipoptional", "true", 0); } if (accept_tos) { XMLRPC_VectorAppendString(params, "agree_to_tos", "true", 0); } if (accept_critical_message) { XMLRPC_VectorAppendString(params, "read_critical", "true", 0); } XMLRPC_VectorAppendInt(params, "last_exec_event", (int) last_exec_froze); // append optional requests in an array XMLRPC_VALUE options = XMLRPC_CreateVector("options", xmlrpc_vector_array); std::vector<const char*>::const_iterator it = requested_options.begin(); std::vector<const char*>::const_iterator end = requested_options.end(); for( ; it < end; ++it) { XMLRPC_VectorAppendString(options, NULL, (*it), 0); } XMLRPC_AddValueToVector(params, options); // put the parameters on the request XMLRPC_RequestSetData(request, params); // Post the XML RPC. mResponder = new XMLRPCResponder; LLHTTPClient::postXMLRPC(auth_uri, request, mResponder); LL_INFOS2("AppInit", "Authentication") << "LLUserAuth::authenticate: uri=" << auth_uri << LL_ENDL; }
XMLRPC_VALUE xml_element_to_XMLRPC_REQUEST_worker(XMLRPC_REQUEST request, XMLRPC_VALUE parent_vector, XMLRPC_VALUE current_val, xml_element* el) { if (!current_val) { /* This should only be the case for the first element */ current_val = XMLRPC_CreateValueEmpty(); } if (el->name) { /* first, deal with the crazy/stupid fault format */ if (!strcmp(el->name, ELEM_FAULT)) { xml_element* fault_value = (xml_element*)Q_Head(&el->children); XMLRPC_SetIsVector(current_val, xmlrpc_vector_struct); if(fault_value) { xml_element* fault_struct = (xml_element*)Q_Head(&fault_value->children); if(fault_struct) { xml_element* iter = (xml_element*)Q_Head(&fault_struct->children); while (iter) { XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty(); xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter); XMLRPC_AddValueToVector(current_val, xNextVal); iter = (xml_element*)Q_Next(&fault_struct->children); } } } } else if (!strcmp(el->name, ELEM_DATA) /* should be ELEM_ARRAY, but there is an extra level. weird */ || (!strcmp(el->name, ELEM_PARAMS) && (XMLRPC_RequestGetRequestType(request) == xmlrpc_request_call)) ) { /* this "PARAMS" concept is silly. dave?! */ xml_element* iter = (xml_element*)Q_Head(&el->children); XMLRPC_SetIsVector(current_val, xmlrpc_vector_array); while (iter) { XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty(); xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter); XMLRPC_AddValueToVector(current_val, xNextVal); iter = (xml_element*)Q_Next(&el->children); } } else if (!strcmp(el->name, ELEM_STRUCT)) { xml_element* iter = (xml_element*)Q_Head(&el->children); XMLRPC_SetIsVector(current_val, xmlrpc_vector_struct); while ( iter ) { XMLRPC_VALUE xNextVal = XMLRPC_CreateValueEmpty(); xml_element_to_XMLRPC_REQUEST_worker(request, current_val, xNextVal, iter); XMLRPC_AddValueToVector(current_val, xNextVal); iter = (xml_element*)Q_Next(&el->children); } } else if (!strcmp(el->name, ELEM_STRING) || (!strcmp(el->name, ELEM_VALUE) && Q_Size(&el->children) == 0)) { XMLRPC_SetValueString(current_val, el->text.str, el->text.len); } else if (!strcmp(el->name, ELEM_NAME)) { XMLRPC_SetValueID_Case(current_val, el->text.str, 0, xmlrpc_case_exact); } else if (!strcmp(el->name, ELEM_INT) || !strcmp(el->name, ELEM_I4)) { XMLRPC_SetValueInt(current_val, atoi(el->text.str)); } else if (!strcmp(el->name, ELEM_BOOLEAN)) { XMLRPC_SetValueBoolean(current_val, atoi(el->text.str)); } else if (!strcmp(el->name, ELEM_DOUBLE)) { XMLRPC_SetValueDouble(current_val, atof(el->text.str)); } else if (!strcmp(el->name, ELEM_DATETIME)) { XMLRPC_SetValueDateTime_ISO8601(current_val, el->text.str); } else if (!strcmp(el->name, ELEM_BASE64)) { struct buffer_st buf; base64_decode(&buf, el->text.str, el->text.len); XMLRPC_SetValueBase64(current_val, buf.data, buf.offset); buffer_delete(&buf); } else { xml_element* iter; if (!strcmp(el->name, ELEM_METHODCALL)) { if (request) { XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); } } else if (!strcmp(el->name, ELEM_METHODRESPONSE)) { if (request) { XMLRPC_RequestSetRequestType(request, xmlrpc_request_response); } } else if (!strcmp(el->name, ELEM_METHODNAME)) { if (request) { XMLRPC_RequestSetMethodName(request, el->text.str); } } iter = (xml_element*)Q_Head(&el->children); while ( iter ) { xml_element_to_XMLRPC_REQUEST_worker(request, parent_vector, current_val, iter); iter = (xml_element*)Q_Next(&el->children); } } } return current_val; }
void LLXMLRPCValue::append(LLXMLRPCValue& v) { XMLRPC_AddValueToVector(mV, v.mV); }
void LLXMLRPCValue::appendBool(const char* id, bool v) { XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueBoolean(id, v)); }
void LLXMLRPCValue::append(const char* id, LLXMLRPCValue& v) { XMLRPC_SetValueID(v.mV, id, 0); XMLRPC_AddValueToVector(mV, v.mV); }
/* convert an xml tree conforming to spec <url tbd> to XMLRPC_VALUE * suitable for use with XMLRPC_ServerAddIntrospectionData */ XMLRPC_VALUE xml_element_to_method_description(xml_element* el, XMLRPC_ERROR err) { XMLRPC_VALUE xReturn = NULL; if(el->name) { const char* name = NULL; const char* type = NULL; const char* basetype = NULL; const char* desc = NULL; const char* def = NULL; int optional = 0; xml_element_attr* attr_iter = Q_Head(&el->attrs); /* grab element attributes up front to save redundant while loops */ while(attr_iter) { if(!strcmp(attr_iter->key, "name")) { name = attr_iter->val; } else if(!strcmp(attr_iter->key, "type")) { type = attr_iter->val; } else if(!strcmp(attr_iter->key, "basetype")) { basetype = attr_iter->val; } else if(!strcmp(attr_iter->key, "desc")) { desc = attr_iter->val; } else if(!strcmp(attr_iter->key, "optional")) { if(attr_iter->val && !strcmp(attr_iter->val, "yes")) { optional = 1; } } else if(!strcmp(attr_iter->key, "default")) { def = attr_iter->val; } attr_iter = Q_Next(&el->attrs); } /* value and typeDescription behave about the same */ if(!strcmp(el->name, "value") || !strcmp(el->name, "typeDescription")) { XMLRPC_VALUE xSubList = NULL; const char* ptype = !strcmp(el->name, "value") ? type : basetype; if(ptype) { if(Q_Size(&el->children) && (!strcmp(ptype, "array") || !strcmp(ptype, "struct") || !strcmp(ptype, "mixed"))) { xSubList = XMLRPC_CreateVector("member", xmlrpc_vector_array); if(xSubList) { xml_element* elem_iter = Q_Head(&el->children); while(elem_iter) { XMLRPC_AddValueToVector(xSubList, xml_element_to_method_description(elem_iter, err)); elem_iter = Q_Next(&el->children); } } } xReturn = describeValue_worker(ptype, name, (desc ? desc : (xSubList ? NULL : el->text.str)), optional, def, xSubList); } } /* these three kids are about equivalent */ else if(!strcmp(el->name, "params") || !strcmp(el->name, "returns") || !strcmp(el->name, "signature")) { if(Q_Size(&el->children)) { xml_element* elem_iter = Q_Head(&el->children); xReturn = XMLRPC_CreateVector(!strcmp(el->name, "signature") ? NULL : el->name, xmlrpc_vector_struct); while(elem_iter) { XMLRPC_AddValueToVector(xReturn, xml_element_to_method_description(elem_iter, err)); elem_iter = Q_Next(&el->children); } } } else if(!strcmp(el->name, "methodDescription")) { xml_element* elem_iter = Q_Head(&el->children); xReturn = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); XMLRPC_VectorAppendString(xReturn, xi_token_name, name, 0); while(elem_iter) { XMLRPC_AddValueToVector(xReturn, xml_element_to_method_description(elem_iter, err)); elem_iter = Q_Next(&el->children); } } /* items are slightly special */ else if(!strcmp(el->name, "item")) { xReturn = XMLRPC_CreateValueString(name, el->text.str, el->text.len); } /* sure. we'll let any ol element with children through */ else if(Q_Size(&el->children)) { xml_element* elem_iter = Q_Head(&el->children); xReturn = XMLRPC_CreateVector(el->name, xmlrpc_vector_mixed); while(elem_iter) { XMLRPC_AddValueToVector(xReturn, xml_element_to_method_description(elem_iter, err)); elem_iter = Q_Next(&el->children); } } /* or anything at all really, so long as its got some text. * no reason being all snotty about a spec, right? */ else if(el->name && el->text.len) { xReturn = XMLRPC_CreateValueString(el->name, el->text.str, el->text.len); } } return xReturn; }
void LLXMLRPCValue::appendInt(const char* id, int v) { XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueInt(id, v)); }
XMLRPC_VALUE xml_element_to_DANDARPC_REQUEST_worker(XMLRPC_REQUEST request, XMLRPC_VALUE xCurrent, xml_element* el) { if(!xCurrent) { xCurrent = XMLRPC_CreateValueEmpty(); } if(el->name) { const char* id = NULL; const char* type = NULL; xml_element_attr* attr_iter = Q_Head(&el->attrs); while(attr_iter) { if(!strcmp(attr_iter->key, ATTR_ID)) { id = attr_iter->val; } if(!strcmp(attr_iter->key, ATTR_TYPE)) { type = attr_iter->val; } attr_iter = Q_Next(&el->attrs); } if(id) { XMLRPC_SetValueID_Case(xCurrent, id, 0, xmlrpc_case_exact); } if(!strcmp(el->name, ATTR_SCALAR)) { if(!type || !strcmp(type, ATTR_STRING)) { XMLRPC_SetValueString(xCurrent, el->text.str, el->text.len); } else if(!strcmp(type, ATTR_INT)) { XMLRPC_SetValueInt(xCurrent, atoi(el->text.str)); } else if(!strcmp(type, ATTR_BOOLEAN)) { XMLRPC_SetValueBoolean(xCurrent, atoi(el->text.str)); } else if(!strcmp(type, ATTR_DOUBLE)) { XMLRPC_SetValueDouble(xCurrent, atof(el->text.str)); } else if(!strcmp(type, ATTR_DATETIME)) { XMLRPC_SetValueDateTime_ISO8601(xCurrent, el->text.str); } else if(!strcmp(type, ATTR_BASE64)) { struct buffer_st buf; base64_decode_xmlrpc(&buf, el->text.str, el->text.len); XMLRPC_SetValueBase64(xCurrent, buf.data, buf.offset); buffer_delete(&buf); } } else if(!strcmp(el->name, ATTR_VECTOR)) { xml_element* iter = (xml_element*)Q_Head(&el->children); if(!type || !strcmp(type, ATTR_MIXED)) { XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_mixed); } else if(!strcmp(type, ATTR_ARRAY)) { XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_array); } else if(!strcmp(type, ATTR_STRUCT)) { XMLRPC_SetIsVector(xCurrent, xmlrpc_vector_struct); } while( iter ) { XMLRPC_VALUE xNext = XMLRPC_CreateValueEmpty(); xml_element_to_DANDARPC_REQUEST_worker(request, xNext, iter); XMLRPC_AddValueToVector(xCurrent, xNext); iter = (xml_element*)Q_Next(&el->children); } } else { xml_element* iter = (xml_element*)Q_Head(&el->children); while( iter ) { xml_element_to_DANDARPC_REQUEST_worker(request, xCurrent, iter); iter = (xml_element*)Q_Next(&el->children); } if(!strcmp(el->name, ELEM_METHODCALL)) { if(request) { XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); } } else if(!strcmp(el->name, ELEM_METHODRESPONSE)) { if(request) { XMLRPC_RequestSetRequestType(request, xmlrpc_request_response); } } else if(!strcmp(el->name, ELEM_METHODNAME)) { if(request) { XMLRPC_RequestSetMethodName(request, el->text.str); } } } } return xCurrent; }
void LLXMLRPCValue::appendDouble(const char* id, double v) { XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueDouble(id, v)); }
// passwd is already MD5 hashed by the time we get to it. void LLUserAuth::authenticate( const std::string& auth_uri, const std::string& method, const std::string& firstname, const std::string& lastname, const std::string& passwd, const std::string& start, BOOL skip_optional, BOOL accept_tos, BOOL accept_critical_message, BOOL last_exec_froze, const std::vector<const char*>& requested_options, const std::string& hashed_mac, const std::string& hashed_volume_serial) { std::string dpasswd("$1$"); dpasswd.append(passwd); LL_INFOS2("AppInit", "Authentication") << "Authenticating: " << firstname << " " << lastname << ", " << /*dpasswd.c_str() <<*/ LL_ENDL; std::ostringstream option_str; option_str << "Options: "; std::ostream_iterator<const char*> appender(option_str, ", "); std::copy(requested_options.begin(), requested_options.end(), appender); option_str << "END"; LL_INFOS2("AppInit", "Authentication") << option_str.str().c_str() << LL_ENDL; mAuthResponse = E_NO_RESPONSE_YET; //mDownloadTimer.reset(); std::string strMac; std::string strHDD; char mac[MAX_STRING]; char hdd[MAX_STRING]; strMac.assign(firstname); strMac.append(lastname); strMac.append(dpasswd.c_str()); strMac.append(hashed_mac.c_str()); strHDD.assign(firstname); strHDD.append(lastname); strHDD.append(dpasswd.c_str()); strHDD.append(hashed_volume_serial.c_str()); LLMD5 md5Mac((const unsigned char *)strMac.c_str()); LLMD5 md5HDD((const unsigned char *)strHDD.c_str()); md5Mac.hex_digest(mac); md5HDD.hex_digest(hdd); // create the request XMLRPC_REQUEST request = XMLRPC_RequestNew(); XMLRPC_RequestSetMethodName(request, method.c_str()); XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); // stuff the parameters XMLRPC_VALUE params = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); XMLRPC_VectorAppendString(params, "first", firstname.c_str(), 0); XMLRPC_VectorAppendString(params, "last", lastname.c_str(), 0); XMLRPC_VectorAppendString(params, "passwd", dpasswd.c_str(), 0); XMLRPC_VectorAppendString(params, "start", start.c_str(), 0); // To log into OpenLife, we need to spoof our version or it complains about an out of date viewer. // This will likely break OpenLife logins through SLProxy! // -Patrick Sapinski (Wednesday, October 21, 2009) if (auth_uri.find("logingrid.net") != -1) { XMLRPC_VectorAppendString(params, "version", "Openlife R17 1.17.0.336", 0); XMLRPC_VectorAppendString(params, "channel", "Second Life Release", 0); //OLG uses the original channel name. } else { XMLRPC_VectorAppendString(params, "version", gCurrentVersion.c_str(), 0); // Includes channel name XMLRPC_VectorAppendString(params, "channel", gSavedSettings.getString("VersionChannelName").c_str(), 0); } XMLRPC_VectorAppendString(params, "platform", PLATFORM_STRING, 0); XMLRPC_VectorAppendString(params, "mac", mac, 0); // A bit of security through obscurity: id0 is volume_serial XMLRPC_VectorAppendString(params, "id0", hdd, 0); if (skip_optional) { XMLRPC_VectorAppendString(params, "skipoptional", "true", 0); } if (accept_tos) { XMLRPC_VectorAppendString(params, "agree_to_tos", "true", 0); } if (accept_critical_message) { XMLRPC_VectorAppendString(params, "read_critical", "true", 0); } XMLRPC_VectorAppendInt(params, "last_exec_event", (int) last_exec_froze); // append optional requests in an array XMLRPC_VALUE options = XMLRPC_CreateVector("options", xmlrpc_vector_array); std::vector<const char*>::const_iterator it = requested_options.begin(); std::vector<const char*>::const_iterator end = requested_options.end(); for( ; it < end; ++it) { XMLRPC_VectorAppendString(options, NULL, (*it), 0); } XMLRPC_AddValueToVector(params, options); // put the parameters on the request XMLRPC_RequestSetData(request, params); mTransaction = new LLXMLRPCTransaction(auth_uri, request); XMLRPC_RequestFree(request, 1); LL_INFOS2("AppInit", "Authentication") << "LLUserAuth::authenticate: uri=" << auth_uri << LL_ENDL; }
void LLXMLRPCValue::appendString(const std::string& v) { XMLRPC_AddValueToVector(mV, XMLRPC_CreateValueString(NULL, v.c_str(), 0)); }
// passwd is already MD5 hashed by the time we get to it. void LLUserAuth::authenticate( const std::string& auth_uri, const std::string& method, const std::string& firstname, const std::string& lastname, const std::string& passwd, const std::string& start, BOOL skip_optional, BOOL accept_tos, BOOL accept_critical_message, BOOL last_exec_froze, const std::vector<const char*>& requested_options, const std::string& hashed_mac, const std::string& hashed_volume_serial) { std::string dpasswd("$1$"); dpasswd.append(passwd); LL_INFOS2("AppInit", "Authentication") << "Authenticating: " << firstname << " " << lastname << ", " << /*dpasswd.c_str() <<*/ LL_ENDL; std::ostringstream option_str; option_str << "Options: "; std::ostream_iterator<const char*> appender(option_str, ", "); std::copy(requested_options.begin(), requested_options.end(), appender); option_str << "END"; LL_INFOS2("AppInit", "Authentication") << option_str.str().c_str() << LL_ENDL; mAuthResponse = E_NO_RESPONSE_YET; //mDownloadTimer.reset(); // create the request XMLRPC_REQUEST request = XMLRPC_RequestNew(); XMLRPC_RequestSetMethodName(request, method.c_str()); XMLRPC_RequestSetRequestType(request, xmlrpc_request_call); // stuff the parameters XMLRPC_VALUE params = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct); XMLRPC_VectorAppendString(params, "first", firstname.c_str(), 0); XMLRPC_VectorAppendString(params, "last", lastname.c_str(), 0); XMLRPC_VectorAppendString(params, "passwd", dpasswd.c_str(), 0); XMLRPC_VectorAppendString(params, "start", start.c_str(), 0); // <edit> //XMLRPC_VectorAppendString(params, "version", gCurrentVersion.c_str(), 0); // Includes channel name //XMLRPC_VectorAppendString(params, "channel", gSavedSettings.getString("VersionChannelName").c_str(), 0); //WOW NEIL YOU ARE SO AWESOME!! XMLRPC_VectorAppendString(params, "version", std::string( gSavedSettings.getString("SpecifiedChannel") + " " + llformat("%d", gSavedSettings.getU32("SpecifiedVersionMaj")) + "." + llformat("%d", gSavedSettings.getU32("SpecifiedVersionMin")) + "." + llformat("%d", gSavedSettings.getU32("SpecifiedVersionPatch")) + "." + llformat("%d", gSavedSettings.getU32("SpecifiedVersionBuild")) ).c_str(), 0); // Includes channel name XMLRPC_VectorAppendString(params, "channel", gSavedSettings.getString("SpecifiedChannel").c_str(), 0); // </edit> XMLRPC_VectorAppendString(params, "platform", PLATFORM_STRING, 0); // <edit> if(gSavedSettings.getBOOL("SpecifyMAC")) XMLRPC_VectorAppendString(params, "mac", gSavedSettings.getString("SpecifiedMAC").c_str(), 0); else // </edit> XMLRPC_VectorAppendString(params, "mac", hashed_mac.c_str(), 0); // A bit of security through obscurity: id0 is volume_serial // <edit> if(gSavedSettings.getBOOL("SpecifyID0")) XMLRPC_VectorAppendString(params, "id0", gSavedSettings.getString("SpecifiedID0").c_str(), 0); else // </edit> XMLRPC_VectorAppendString(params, "id0", hashed_volume_serial.c_str(), 0); if (skip_optional) { XMLRPC_VectorAppendString(params, "skipoptional", "true", 0); } if (accept_tos) { XMLRPC_VectorAppendString(params, "agree_to_tos", "true", 0); } if (accept_critical_message) { XMLRPC_VectorAppendString(params, "read_critical", "true", 0); } XMLRPC_VectorAppendInt(params, "last_exec_event", (int) last_exec_froze); // append optional requests in an array XMLRPC_VALUE options = XMLRPC_CreateVector("options", xmlrpc_vector_array); std::vector<const char*>::const_iterator it = requested_options.begin(); std::vector<const char*>::const_iterator end = requested_options.end(); for( ; it < end; ++it) { XMLRPC_VectorAppendString(options, NULL, (*it), 0); } XMLRPC_AddValueToVector(params, options); // put the parameters on the request XMLRPC_RequestSetData(request, params); mTransaction = new LLXMLRPCTransaction(auth_uri, request); XMLRPC_RequestFree(request, 1); LL_INFOS2("AppInit", "Authentication") << "LLUserAuth::authenticate: uri=" << auth_uri << LL_ENDL; }