Beispiel #1
0
Datei: you.c Projekt: joeshaw/rcd
static xmlrpc_value *
you_abort_download (xmlrpc_env   *env,
                    xmlrpc_value *param_array,
                    void         *user_data)
{
    int download_id;
    RCDRPCMethodData *method_data;
    int success;
    xmlrpc_value *result = NULL;

    xmlrpc_parse_value (env, param_array, "(i)", &download_id);

    if (!rc_you_transaction_is_valid (download_id)) {
        xmlrpc_env_set_fault (env, RCD_RPC_FAULT_INVALID_TRANSACTION_ID,
                              "Cannot find transaction for that id");
        return NULL;
    }

    method_data = rcd_rpc_get_method_data ();

    success = rc_you_transaction_abort (download_id, method_data->identity);

    if (success < 0) {
        xmlrpc_env_set_fault (env, RCD_RPC_FAULT_PERMISSION_DENIED,
                              "Permission denied");
        return NULL;
    }

    result = xmlrpc_build_value (env, "i", success);

    return result;
}
int xr_flush_response_array(xmlrpc_env * env, struct mi_root *tree)
{
    str buf;

    buf.s = reply_buffer;
    buf.len = reply_buffer_len;

    /* test if mi root value is 200 OK (if not no point to continue) */
    if ( tree->code<200 || tree->code>=300 ) {
        LM_DBG("command processing failure: %s\n", tree->reason.s);
        if (tree->reason.s)
            xmlrpc_env_set_fault(env, tree->code, tree->reason.s);
        else
            xmlrpc_env_set_fault(env, tree->code, "Error");
        goto error;
    }

    if ( recur_flush_response_array(env, (&tree->node)->kids, &buf) != 0 ) {
        LM_ERR("failed to read from the MI tree!\n");
        xmlrpc_env_set_fault(env, 500, "Failed to write reply");
        goto error;
    }

    return 0;

error:
    if ( reply_buffer ) pkg_free(reply_buffer);
    return -1;
}
char* xr_flush_response( xmlrpc_env * env, struct mi_root * tree )
{
    str buf;

    buf.s = reply_buffer;
    buf.len = reply_buffer_len;

    if ( tree->code<200 || tree->code>=300 ) {
        LM_DBG("command processing failure: %s\n", tree->reason.s);
        if (tree->reason.s)
            xmlrpc_env_set_fault(env, tree->code, tree->reason.s);
        else
            xmlrpc_env_set_fault(env, tree->code, "Error");
        return 0;
    }

    if ( recur_flush_response(env, (&tree->node)->kids, &buf) != 0 ) {
        LM_ERR("failed to read from the MI tree!\n");
        xmlrpc_env_set_fault(env, 500, "Failed to build reply");
        return 0;
    }

    reply_buffer[reply_buffer_len-buf.len] = 0;

    return reply_buffer;
}
Beispiel #4
0
Datei: you.c Projekt: joeshaw/rcd
static xmlrpc_value *
you_find_latest_version (xmlrpc_env   *env,
                         xmlrpc_value *param_array,
                         void         *user_data)
{
    RCWorld *world = (RCWorld *) user_data;
    char *name = NULL;
    gboolean subscribed_only;
    LatestVersionInfo info;
    xmlrpc_value *result = NULL;

    xmlrpc_parse_value (env, param_array, "(sb)", &name, &subscribed_only);
    XMLRPC_FAIL_IF_FAULT (env);

    info.world = world;
    info.patch = NULL;
    info.installed_patch = NULL;
    info.subscribed_only = subscribed_only;

    rc_world_multi_foreach_patch_by_name
        (RC_WORLD_MULTI (world), name, RC_CHANNEL_SYSTEM,
         find_latest_installed_version, &info);
    rc_world_multi_foreach_patch_by_name
        (RC_WORLD_MULTI (world), name, RC_CHANNEL_NON_SYSTEM,
         find_latest_version, &info);

    if (!info.patch) {
        if (info.installed_patch) {
            /* No version in a channel newer than what is on the system. */
            xmlrpc_env_set_fault (env, RCD_RPC_FAULT_PACKAGE_IS_NEWEST,
                                  "Installed version is newer than the "
                                  "newest available version");
        } else {
            /* Can't find a patch by that name at all. */
            xmlrpc_env_set_fault (env, RCD_RPC_FAULT_PACKAGE_NOT_FOUND,
                                  "Couldn't find patch");
        }

        return NULL;
    }

    result = rc_you_patch_to_xmlrpc (info.patch, env);

 cleanup:
    if (env->fault_occurred)
        return NULL;

    return result;
}
xmlrpc_value * std_getblock(xmlrpc_env *   envP,
               xmlrpc_value * paramArrayP,
               void *         serverInfo,
               void *         channelInfo) {

    xmlrpc_value * retvalP;
    xmlrpc_int32 CheckSum;
    xmlrpc_value * DataStructP;

    xmlrpc_decompose_value(envP, paramArrayP, "(iS)",
                           &CheckSum, &DataStructP);
    if (envP->fault_occurred)
        return NULL;

    if (CheckSum != 100) {
        xmlrpc_env_set_fault(envP, 0, "Parameter list version must be 1");
        return NULL;
    }

    getDataBlock(envP, DataStructP, &retvalP);
    
    xmlrpc_DECREF(DataStructP);

    if (envP->fault_occurred)
        return NULL;

    return retvalP;
}
Beispiel #6
0
xmlrpc_value *
xmlrpc_parse_response(xmlrpc_env * const envP,
                      const char * const xmlData,
                      size_t       const xmlDataLen) {
/*----------------------------------------------------------------------------
   This exists for backward compatibility.  It is like
   xmlrpc_parse_response2(), except that it merges the concepts of a
   failed RPC and an error in executing the RPC.
-----------------------------------------------------------------------------*/
    xmlrpc_value * retval;
    xmlrpc_value * result;
    const char * faultString;
    int faultCode;

    xmlrpc_parse_response2(envP, xmlData, xmlDataLen,
                           &result, &faultCode, &faultString);
    
    if (envP->fault_occurred)
        retval = NULL;
    else {
        if (faultString) {
            xmlrpc_env_set_fault(envP, faultCode, faultString);
            xmlrpc_strfree(faultString);
            retval = NULL;
        } else
            retval = result;  /* transfer reference */
    }
    return retval;
}
static void
test_serialize_fault(void) {
    /* Serialize a fault. */

    xmlrpc_env env;
    xmlrpc_env fault;
    xmlrpc_mem_block *output;
    size_t size;
    
    xmlrpc_env_init(&env);

    output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
    TEST_NO_FAULT(&env);
    xmlrpc_env_init(&fault);
    xmlrpc_env_set_fault(&fault, 6, "A fault occurred");
    xmlrpc_serialize_fault(&env, output, &fault);
    TEST_NO_FAULT(&env);

    /* Make sure we serialized the correct value. */
    size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
    TEST(size == strlen(serialized_fault));
    TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
                serialized_fault, size) == 0);

    /* Clean up our fault. */
    xmlrpc_env_clean(&fault);
    XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);

    xmlrpc_env_clean(&env);
}
static void test_env(void)
{
    xmlrpc_env env, env2;
    char *s;

    /* Test xmlrpc_env_init. */
    xmlrpc_env_init(&env);
    TEST(!env.fault_occurred);
    TEST(env.fault_code == 0);
    TEST(env.fault_string == NULL);

    /* Test xmlrpc_set_fault. */
    xmlrpc_env_set_fault(&env, 1, test_string_1);
    TEST(env.fault_occurred);
    TEST(env.fault_code == 1);
    TEST(env.fault_string != test_string_1);
    TEST(strcmp(env.fault_string, test_string_1) == 0);

    /* Change an existing fault. */
    xmlrpc_env_set_fault(&env, 2, test_string_2);
    TEST(env.fault_occurred);
    TEST(env.fault_code == 2);
    TEST(strcmp(env.fault_string, test_string_2) == 0);    

    /* Set a fault with a format string. */
    xmlrpc_env_set_fault_formatted(&env, 3, "a%s%d", "bar", 9);
    TEST(env.fault_occurred);
    TEST(env.fault_code == 3);
    TEST(strcmp(env.fault_string, "abar9") == 0);

    /* Set a fault with an oversized string. */
    s = "12345678901234567890123456789012345678901234567890";
    xmlrpc_env_set_fault_formatted(&env, 4, "%s%s%s%s%s%s", s, s, s, s, s, s);
    TEST(env.fault_occurred);
    TEST(env.fault_code == 4);
    TEST(strlen(env.fault_string) == 255);

    /* Test cleanup code (with help from memprof). */
    xmlrpc_env_clean(&env);

    /* Test cleanup code on in absence of xmlrpc_env_set_fault. */
    xmlrpc_env_init(&env2);
    xmlrpc_env_clean(&env2);
}
static void handleAuthorization(
		xmlrpc_env * envP,
        char * userid,
        char * password)
{
	if (strcmp(userid,"jrandom")==0 && strcmp(password,"secret")==0)
		return;

	xmlrpc_env_set_fault( envP, XMLRPC_REQUEST_REFUSED_ERROR, 
						  "Username and/or password do not match.");
}
Beispiel #10
0
/*
 * Make an XML-RPC call to methodName. This uses the curl client to make
 * a connection over SSL using the CA cert that should have been installed
 * by ipa-client-install.
 */
static void
callRPC(char * user_agent,
     xmlrpc_env *            const envP,
     xmlrpc_server_info * const serverInfoP,
     const char *               const methodName,
     xmlrpc_value *             const paramArrayP,
     xmlrpc_value **            const resultPP) {

    struct xmlrpc_clientparms clientparms;
    struct xmlrpc_curl_xportparms * curlXportParmsP = NULL;
    xmlrpc_client * clientP = NULL;

    memset(&clientparms, 0, sizeof(clientparms));

    XMLRPC_ASSERT(xmlrpc_value_type(paramArrayP) == XMLRPC_TYPE_ARRAY);

    curlXportParmsP = malloc(sizeof(*curlXportParmsP));
    if (curlXportParmsP == NULL) {
        xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, _("Out of memory!"));
        return;
    }
    memset(curlXportParmsP, 0, sizeof(*curlXportParmsP));

    /* Have curl do SSL certificate validation */
    curlXportParmsP->no_ssl_verifypeer = 0;
    curlXportParmsP->no_ssl_verifyhost = 0;
    curlXportParmsP->cainfo = "/etc/ipa/ca.crt";
    curlXportParmsP->user_agent = user_agent;
    /* Enable GSSAPI credentials delegation */
    curlXportParmsP->gssapi_delegation = 1;

    clientparms.transport = "curl";
    clientparms.transportparmsP = (struct xmlrpc_xportparms *)
            curlXportParmsP;
    clientparms.transportparm_size = XMLRPC_CXPSIZE(gssapi_delegation);
    xmlrpc_client_create(envP, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION,
                         &clientparms, sizeof(clientparms),
                         &clientP);

    /* Set up kerberos negotiate authentication in curl. */
    xmlrpc_server_info_set_user(envP, serverInfoP, ":", "");
    xmlrpc_server_info_allow_auth_negotiate(envP, serverInfoP);

    /* Perform the XML-RPC call */
    if (!envP->fault_occurred) {
        xmlrpc_client_call2(envP, clientP, serverInfoP, methodName, paramArrayP, resultPP);
    }

    /* Cleanup */
    xmlrpc_server_info_free(serverInfoP);
    xmlrpc_client_destroy(clientP);
    free((void*)clientparms.transportparmsP);
}
Beispiel #11
0
setError(xmlrpc_env * const envP, const char format[], ...) {
    va_list args;
    const char * faultString;

    va_start(args, format);

    cvasprintf(&faultString, format, args);
    va_end(args);

    xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR, faultString);

    strfree(faultString);
}
Beispiel #12
0
void
xmlrpc_set_fault_formatted_v(xmlrpc_env * const envP,
                             int          const code,
                             const char * const format,
                             va_list            args) {

    const char * faultDescription;

    xmlrpc_vasprintf(&faultDescription, format, args);

    xmlrpc_env_set_fault(envP, code, faultDescription);

    xmlrpc_strfree(faultDescription);
}
static void
set_fault_formatted_v(xmlrpc_env * const envP,
                      int          const code,
                      const char * const format,
                      va_list      const args) {

    char buffer[ERROR_BUFFER_SZ];

    vsnprintf(buffer, ERROR_BUFFER_SZ, format, args);

    /* vsnprintf is guaranteed to terminate the buffer, but we're paranoid. */
    buffer[ERROR_BUFFER_SZ - 1] = '\0';

    /* Set the fault. */
    xmlrpc_env_set_fault(envP, code, buffer);
}
static xmlrpc_value *
test_bar(xmlrpc_env *   const envP,
         xmlrpc_value * const paramArrayP,
         void *         const userData) {

    xmlrpc_int32 x, y;

    TEST_NO_FAULT(envP);
    TEST(paramArrayP != NULL);
    TEST(userData == BAR_USER_DATA);

    xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
    TEST_NO_FAULT(envP);
    TEST(x == 25);
    TEST(y == 17);

    xmlrpc_env_set_fault(envP, 123, "Test fault");

    return NULL;
}
static void
getValueChild(xmlrpc_env *    const envP,
              xml_element *   const parentP,
              xml_element * * const childPP) {

    xml_element ** const children   = xml_element_children(parentP);
    size_t         const childCount = xml_element_children_size(parentP);

    xml_element * childP;
    unsigned int i;

    for (i = 0, childP = NULL; i < childCount && !childP; ++i) {
        if (xmlrpc_streq(xml_element_name(children[i]), "value"))
            childP = children[i];
    }
    if (!childP)
        xmlrpc_env_set_fault(envP, XMLRPC_PARSE_ERROR,
                             "<member> has no <value> child");
    else
        *childPP = childP;
}
Beispiel #16
0
static void
access_control_check (xmlrpc_env   *env,
                      char         *method_name,
                      xmlrpc_value *param_array,
                      void         *user_data)
{
    RCDIdentity *identity = (RCDIdentity *) user_data;
    RCDRPCMethodInfo *method_info;
    char *str;

    g_assert (identity != NULL);

    method_info = g_hash_table_lookup (method_info_hash, method_name);

    rc_debug (RC_DEBUG_LEVEL_DEBUG, 
              "Method being called: %s", method_name);

    if (method_info) {
        str = rcd_privileges_to_string (method_info->req_privs);
        rc_debug (RC_DEBUG_LEVEL_DEBUG,
                  "Requires Privileges: %s", str);
        g_free (str);
              
    }

    str = rcd_privileges_to_string (identity->privileges);
    rc_debug (RC_DEBUG_LEVEL_DEBUG,
              "    User Privileges: %s", str);
    g_free (str);

    if (method_info
        && ! rcd_identity_approve_action (identity, method_info->req_privs)) {
        
        xmlrpc_env_set_fault (env, RCD_RPC_FAULT_PERMISSION_DENIED, 
                              "Permission denied");
            
        rc_debug (RC_DEBUG_LEVEL_MESSAGE, "Unable to approve action");
    }
} /* access_control_check */
Beispiel #17
0
static xmlrpc_value *
test_bar(xmlrpc_env *   const envP,
         xmlrpc_value * const paramArrayP,
         void *         const serverInfo,
         void *         const callInfo) {

    xmlrpc_int32 x, y;

    TEST_NO_FAULT(envP);
    TEST(paramArrayP != NULL);
    TEST(serverInfo == BAR_SERVERINFO);
    TEST(callInfo == BAR_CALLINFO || callInfo == MULTI_CALLINFO);

    xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
    TEST_NO_FAULT(envP);
    TEST(x == 25);
    TEST(y == 17);

    xmlrpc_env_set_fault(envP, 123, "Test fault");

    return NULL;
}
Beispiel #18
0
static xmlrpc_mem_block *
serialize_fault (int fault_code, const char *fault_string)
{
    xmlrpc_env tmp_env;
    xmlrpc_env fault;
    xmlrpc_mem_block *output;

    xmlrpc_env_init (&tmp_env);
    xmlrpc_env_init (&fault);

    output = xmlrpc_mem_block_new (&tmp_env, 0);
    XMLRPC_FAIL_IF_FAULT (&tmp_env);

    xmlrpc_env_set_fault (&fault, fault_code, (char *) fault_string);

    xmlrpc_serialize_fault (&tmp_env, output, &fault);
    XMLRPC_FAIL_IF_FAULT (&tmp_env);

    return output;

cleanup:
    return NULL;
} /* serialize_fault */
/*
 * This is a blocking function that merely sits on the request queue
 * for our URI and processes them one at a time.  Once a request comes
 * in, we check it for content-type, content-length, and verb.  As long
 * as the initial validations are done, we pass the request to the 
 * processRPCCall() function, which collects the body of the request
 * and processes it.  If we get an error back other than network type,
 * we are responsible for notifing the client.
 */
DWORD
DoReceiveRequests(
    IN HANDLE hReqQueue,
    const xmlrpc_server_httpsys_parms * const parmsP
    )
{
    ULONG              result;
    HTTP_REQUEST_ID    requestId;
    DWORD              bytesRead;
    PHTTP_REQUEST      pRequest;
    PCHAR              pRequestBuffer;
    ULONG              RequestBufferLength;
    xmlrpc_env          env;
    char                szHeaderBuf[255];
    long                lContentLength;

    // Allocate a 2K buffer. Should be good for most requests, we'll grow 
    // this if required. We also need space for a HTTP_REQUEST structure.
    RequestBufferLength = sizeof(HTTP_REQUEST) + 2048;
    pRequestBuffer      = (PCHAR) ALLOC_MEM( RequestBufferLength );
    if (pRequestBuffer == NULL)
    {
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    pRequest = (PHTTP_REQUEST)pRequestBuffer;

    // Wait for a new request -- This is indicated by a NULL request ID.
    HTTP_SET_NULL_ID( &requestId );
    for(;;)
    {
        RtlZeroMemory(pRequest, RequestBufferLength);

        result = HttpReceiveHttpRequest(
            hReqQueue,          // Req Queue
            requestId,          // Req ID
            0,                  // Flags
            pRequest,           // HTTP request buffer
            RequestBufferLength,// req buffer length
            &bytesRead,         // bytes received
            NULL                // LPOVERLAPPED
            );

        if(NO_ERROR == result)
        {
            // Got a request with a filled buffer.
            switch(pRequest->Verb)
            {
                case HttpVerbPOST:

                    TraceW(L"Got a POST request for %ws",
                           pRequest->CookedUrl.pFullUrl);              
                    
                    //Check if we need use authorization.
                    if(parmsP->authfn)
                    {
                        xmlrpc_env_init(&env);
                        if(pRequest->Headers.KnownHeaders[
                            HttpHeaderAuthorization].RawValueLength
                           < 6)
                        {
                            xmlrpc_env_set_fault(
                                &env, XMLRPC_REQUEST_REFUSED_ERROR, 
                                "Authorization header too short.");
                        }
                        else
                        {
                            //unencode the headers
                            if(_strnicmp(
                                "basic",
                                pRequest->Headers.KnownHeaders[
                                    HttpHeaderAuthorization].pRawValue,5)
                               !=0)
                            {
#ifndef  NDEBUG
                                PCHAR pTmp = (PCHAR)
                                    ALLOC_MEM(pRequest->Headers.KnownHeaders[
                                        HttpHeaderAuthorization
                                        ].RawValueLength + 1 );
                                if( pTmp ) {
                                    strncpy(pTmp,
                                            pRequest->Headers.KnownHeaders[
                                                HttpHeaderAuthorization
                                                ].pRawValue,
                                            pRequest->Headers.KnownHeaders[
                                                HttpHeaderAuthorization
                                                ].RawValueLength );
                                    pTmp[pRequest->Headers.KnownHeaders[
                                        HttpHeaderAuthorization
                                        ].RawValueLength] = 0;
                                    TraceA("Got HEADER [%s]",pTmp);
                                    FREE_MEM(pTmp);
                                }
#endif   /* #ifndef NDEBUG */
                                xmlrpc_env_set_fault(
                                    &env, XMLRPC_REQUEST_REFUSED_ERROR, 
                                    "Authorization header does not start "
                                    "with type 'basic'!");
                            }
                            else
                            {
                                xmlrpc_mem_block * decoded;
                                
                                decoded =
                                    xmlrpc_base64_decode(
                                        &env,
                                        pRequest->Headers.KnownHeaders[
                                            HttpHeaderAuthorization
                                            ].pRawValue+6,
                                        pRequest->Headers.KnownHeaders[
                                            HttpHeaderAuthorization
                                            ].RawValueLength-6);
                                if(!env.fault_occurred)
                                {
                                    char *pDecodedStr;
                                    char *pUser;
                                    char *pPass;
                                    char *pColon;
                                    
                                    pDecodedStr = (char*)
                                        malloc(decoded->_size+1);
                                    memcpy(pDecodedStr,
                                           decoded->_block,
                                           decoded->_size);
                                    pDecodedStr[decoded->_size]='\0';
                                    pUser = pPass = pDecodedStr;
                                    pColon=strchr(pDecodedStr,':');
                                    if(pColon)
                                    {
                                        *pColon='\0';
                                        pPass=pColon+1;
                                        //The authfn should set env to
                                        //fail if auth is denied.
                                        parmsP->authfn(&env,pUser,pPass);
                                    }
                                    else
                                    {
                                        xmlrpc_env_set_fault(
                                            &env,
                                            XMLRPC_REQUEST_REFUSED_ERROR, 
                                            "Decoded auth not of the correct "
                                            "format.");
                                    }
                                    free(pDecodedStr);
                                }
                                if(decoded)
                                    XMLRPC_MEMBLOCK_FREE(char, decoded);
                            }
                        }
                        if(env.fault_occurred)
                        {
                            //request basic authorization, as the user
                            //did not provide it.
                            xmlrpc_env_clean(&env);
                            TraceW(L"POST request did not provide valid "
                                   L"authorization header.");
                            result =
                                SendHttpResponseAuthRequired( hReqQueue,
                                                              pRequest);
                            break;
                        }
                        xmlrpc_env_clean(&env);
                    }
                    
                    //Check content type to make sure it is text/xml.
                    memcpy(szHeaderBuf,
                           pRequest->Headers.KnownHeaders[
                               HttpHeaderContentType
                               ].pRawValue,
                           pRequest->Headers.KnownHeaders[
                               HttpHeaderContentType
                               ].RawValueLength);
                    szHeaderBuf[pRequest->Headers.KnownHeaders[
                        HttpHeaderContentType
                        ].RawValueLength] = '\0';
                    if (_stricmp(szHeaderBuf,"text/xml")!=0)
                    {
                        //We handle only text/xml data.  Anything else
                        //is not valid.
                        TraceW(L"POST request had an unrecognized "
                               L"content-type: %s", szHeaderBuf);
                        result = SendHttpResponse(
                            hReqQueue, 
                            pRequest,
                            400,
                            "Bad Request",
                            NULL
                            );
                        break;
                    }

                    //Check content length to make sure it exists and
                    //is not too big.
                    memcpy(szHeaderBuf,
                           pRequest->Headers.KnownHeaders[
                               HttpHeaderContentLength
                               ].pRawValue,
                           pRequest->Headers.KnownHeaders[
                               HttpHeaderContentLength
                               ].RawValueLength);
                    szHeaderBuf[pRequest->Headers.KnownHeaders[
                        HttpHeaderContentLength
                        ].RawValueLength]='\0';
                    lContentLength = atol(szHeaderBuf);
                    if (lContentLength<=0)
                    {
                        //Make sure a content length was supplied.
                        TraceW(L"POST request did not include a "
                               L"content-length", szHeaderBuf);
                        result = SendHttpResponse(
                            hReqQueue, 
                            pRequest,
                            411,
                            "Length Required",
                            NULL
                            );
                        break;
                    }                       
                    if((size_t) lContentLength >
                       xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID))
                    {
                        //Content-length is too big for us to handle
                        TraceW(L"POST request content-length is too big "
                               L"for us to handle: %d bytes",
                               lContentLength);
                        result = SendHttpResponse(
                            hReqQueue, 
                            pRequest,
                            500,
                            "content-length too large",
                            NULL
                            );
                        break;
                    }

                    //our initial validations of POST, content-type,
                    //and content-length all check out.  Collect and
                    //pass the complete buffer to the XMLRPC-C library
                    
                    xmlrpc_env_init(&env);
                    processRPCCall(&env,hReqQueue, pRequest);
                    if (env.fault_occurred) 
                    {
                        //if we fail and it is anything other than a
                        //network error, we should return a failure
                        //response to the client.
                        if (env.fault_code != XMLRPC_NETWORK_ERROR)
                        {
                            if (env.fault_string)
                                result = SendHttpResponse(
                                    hReqQueue, 
                                    pRequest,
                                    500,
                                    env.fault_string,
                                    NULL
                                    );
                            else
                                result = SendHttpResponse(
                                    hReqQueue, 
                                    pRequest,
                                    500,
                                    "Unknown Error",
                                    NULL
                                    );
                        }
                    }
                    
                    xmlrpc_env_clean(&env);
                    break;

                default:
                    //We handle only POST data.  Anything else is not valid.
                    TraceW(L"Got an unrecognized Verb request for URI %ws",
                           pRequest->CookedUrl.pFullUrl);
            
                    result = SendHttpResponse(
                        hReqQueue, 
                        pRequest,
                        405,
                        "Method Not Allowed",
                        NULL
                        );
                    break;
            }
            if(result != NO_ERROR)
            {
                break;
            }

            // Reset the Request ID so that we pick up the next request.
            HTTP_SET_NULL_ID( &requestId );
        }
        else if(result == ERROR_MORE_DATA)
        {
            // The input buffer was too small to hold the request headers
            // We have to allocate more buffer & call the API again. 
            //
            // When we call the API again, we want to pick up the request
            // that just failed. This is done by passing a RequestID.
            // This RequestID is picked from the old buffer.
            requestId = pRequest->RequestId;

            // Free the old buffer and allocate a new one.
            RequestBufferLength = bytesRead;
            FREE_MEM( pRequestBuffer );
            pRequestBuffer = (PCHAR) ALLOC_MEM( RequestBufferLength );

            if (pRequestBuffer == NULL)
            {
                result = ERROR_NOT_ENOUGH_MEMORY;
                break;
            }

            pRequest = (PHTTP_REQUEST)pRequestBuffer;

        }
        else if(ERROR_CONNECTION_INVALID == result && 
                !HTTP_IS_NULL_ID(&requestId))
        {
            // The TCP connection got torn down by the peer when we were
            // trying to pick up a request with more buffer. We'll just move
            // onto the next request.            
            HTTP_SET_NULL_ID( &requestId );
        }
        else
        {
            break;
        }

    } // for(;;)

    if(pRequestBuffer)
    {
        FREE_MEM( pRequestBuffer );
    }

    return result;
}
Beispiel #20
0
Datei: you.c Projekt: joeshaw/rcd
static xmlrpc_value *
you_search (xmlrpc_env   *env,
            xmlrpc_value *param_array,
            void         *user_data)
{
    RCWorld *world = (RCWorld *) user_data;
    xmlrpc_value *value = NULL;
    int size = 0;
    RCDQueryPart *parts = NULL;
    int i;
    RCYouPatchSList *rc_you_patches = NULL;
    xmlrpc_value *xmlrpc_patches = NULL;

    xmlrpc_parse_value (env, param_array, "(V)", &value);
    XMLRPC_FAIL_IF_FAULT (env);

    size = xmlrpc_array_size (env, value);
    XMLRPC_FAIL_IF_FAULT (env);

    parts = g_new0 (RCDQueryPart, size + 1);
    for (i = 0; i < size; i++) {
        xmlrpc_value *v;

        v = xmlrpc_array_get_item (env, value, i);
        XMLRPC_FAIL_IF_FAULT (env);

        parts[i] = rcd_xmlrpc_tuple_to_query_part (v, env);
        XMLRPC_FAIL_IF_FAULT (env);

        if (parts[i].type == RCD_QUERY_INVALID) {
            xmlrpc_env_set_fault (env, RCD_RPC_FAULT_INVALID_SEARCH_TYPE,
                                  "Invalid search type");
            goto cleanup;
        }
    }

    parts[i].type = RCD_QUERY_LAST;
    
    rc_you_query_patches (world, parts, add_patch_cb, &rc_you_patches);

    xmlrpc_patches = rc_you_patch_slist_to_xmlrpc_array (rc_you_patches, env);

cleanup:
    if (parts) {
        for (i = 0; i < size; i++) {
            g_free (parts[i].key);
            g_free (parts[i].query_str);
        }
        g_free (parts);
    }

    if (rc_you_patches) {
        rc_you_patch_slist_unref (rc_you_patches);
        g_slist_free (rc_you_patches);
    }

    if (env->fault_occurred)
        return NULL;

    return xmlrpc_patches;
} /* you_search */
Beispiel #21
0
xmlrpc_value*  default_method	(xmlrpc_env* 	env, 
								const char* 	host,
								const char* 	methodName,
								xmlrpc_value* 	paramArray,
								void* 			serverInfo)
#endif
{
	xmlrpc_value* ret = NULL;
	struct mi_root* mi_cmd = NULL;
	struct mi_root* mi_rpl = NULL;
	struct mi_handler *hdl = NULL;
	struct mi_cmd* f;
	char* response = 0;
	int is_shm = 0;

	LM_DBG("starting up.....\n");

	f = lookup_mi_cmd((char*)methodName, strlen(methodName));
	
	if ( f == 0 ) {
		LM_ERR("command %s is not available!\n", methodName);
		xmlrpc_env_set_fault_formatted(env, XMLRPC_NO_SUCH_METHOD_ERROR, 
			"Requested command (%s) is not available!", methodName);
		goto error;
	}

	LM_DBG("done looking the mi command.\n");

	/* if asyncron cmd, build the async handler */
	if (f->flags&MI_ASYNC_RPL_FLAG) {
		hdl = build_async_handler( );
		if (hdl==0) {
			LM_ERR("failed to build async handler\n");
			if ( !env->fault_occurred )
				xmlrpc_env_set_fault(env, XMLRPC_INTERNAL_ERROR,
					"Internal server error while processing request");
			goto error;
		}
	} else {
		hdl = NULL;
	}

	if (f->flags&MI_NO_INPUT_FLAG) {
		mi_cmd = 0;
	} else {
		mi_cmd = xr_parse_tree(env, paramArray);
		if ( mi_cmd == NULL ){
			LM_ERR("failed to parse MI tree\n");
			if ( !env->fault_occurred )
				xmlrpc_env_set_fault(env, XMLRPC_INTERNAL_ERROR,
					"The xmlrpc request could not be parsed into a MI tree!");
			goto error;
		}
		mi_cmd->async_hdl = hdl;
	}

	LM_DBG("done parsing the mi tree.\n");

	if ( ( mi_rpl = run_mi_cmd(f, mi_cmd) ) == 0 ){
		LM_ERR("command (%s) processing failed.\n", methodName);
		xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR, 
			"Command (%s) processing failed.\n", methodName);
		goto error;
	} else if (mi_rpl==MI_ROOT_ASYNC_RPL) {
		mi_rpl = wait_async_reply(hdl);
		hdl = 0;
		if (mi_rpl==0) {
			xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR, 
				"Command (%s) processing failed (async).\n", methodName);
			goto error;
		}
		is_shm = 1;
	}

	LM_DBG("done running the mi command.\n");

	if ( rpl_opt == 1 ) {
		if ( xr_build_response_array( env, mi_rpl ) != 0 ){
			if ( !env->fault_occurred ) {
				LM_ERR("failed parsing the xmlrpc response from the mi tree\n");
				xmlrpc_env_set_fault(env, XMLRPC_INTERNAL_ERROR, 
					"Failed to parse the xmlrpc response from the mi tree.");
				}
			goto error;
		}
		LM_DBG("done building response array.\n");

		ret = xr_response;
	} else {
		if ( (response = xr_build_response( env, mi_rpl )) == 0 ){
			if ( !env->fault_occurred ) {
				LM_ERR("failed parsing the xmlrpc response from the mi tree\n");
				xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR,
					"Failed to parse the xmlrpc response from the mi tree.");
			}
			goto error;
		}
		LM_DBG("done building response.\n");

		ret = xmlrpc_build_value(env, "s", response);
	}

error:
	free_async_handler(hdl);
	if ( mi_cmd ) free_mi_tree( mi_cmd );
	if ( mi_rpl ) { is_shm?free_shm_mi_tree(mi_rpl):free_mi_tree(mi_rpl);}
	return ret;
}
Beispiel #22
0
static xmlrpc_value *
service_refresh_blocking (xmlrpc_env   *env,
                          xmlrpc_value *param_array,
                          void         *user_data)
{
    int size;
    RCWorld *world;
    RCPending *pending = NULL;
    GSList *pending_list;
    char *err_msg = NULL;

    if (rcd_transaction_is_locked ()) {
        xmlrpc_env_set_fault (env, RCD_RPC_FAULT_LOCKED,
                              "Transaction lock in place");
        return NULL;
    }

    size = xmlrpc_array_size (env, param_array);
    XMLRPC_FAIL_IF_FAULT (env);

    if (size > 0) {
        char *service_identifier;

        xmlrpc_parse_value (env, param_array, "(s)", &service_identifier);
        XMLRPC_FAIL_IF_FAULT (env);

        world = RC_WORLD (service_lookup (service_identifier));

        if (!world) {
            xmlrpc_env_set_fault_formatted (env, RCD_RPC_FAULT_INVALID_SERVICE,
                                            "Unable to find service '%s'",
                                            service_identifier);
            goto cleanup;
        }
    } else {
        world = rc_get_world ();
    }

    /* FIXME: err_msg ? */
    pending = rc_world_refresh (world);

    if (err_msg) {
        xmlrpc_env_set_fault_formatted (
            env, RCD_RPC_FAULT_CANT_REFRESH,
            "Unable to download channel data: %s", err_msg);
        goto cleanup;
    }

    pending_list = g_slist_prepend (NULL, pending);
    rcd_rpc_block_on_pending_list (env, pending_list, FALSE,
                                   RCD_RPC_FAULT_CANT_REFRESH);
    g_slist_free (pending_list);

cleanup:
    if (pending)
        g_object_unref (pending);

    if (err_msg)
        g_free (err_msg);

    if (env->fault_occurred)
        return NULL;

    return xmlrpc_build_value (env, "i", 0);
}
/* Function:	build_xml_struct
 * Description:	Build the xmlrpc structure for a given stats
 * Parameters:	N/A
 * Returns:	xml formatted data
 */
static xmlrpc_value *build_xml_struct (xmlrpc_env *const env,
                                       xmlrpc_value *retval,
                                       const char *stats_name,
                                       void *value,
                                       stats_type_e type)
{
    xmlrpc_value *stats_value = NULL;
    char buffer[BUFFER_SIZE];

    switch (type) {
        case XMLRPC_BOOL:
            stats_value = xmlrpc_build_value(env,
                                             "{s:b}",
                                             stats_name,
                                             *((boolean*)value));
            xmlrpc_array_append_item(env, retval, stats_value);
            xmlrpc_DECREF(stats_value);

            break;

        case XMLRPC_INT:
            stats_value = xmlrpc_build_value(env,
                                             "{s:i}",
                                             stats_name,
                                             *((int*)value));
            xmlrpc_array_append_item(env, retval, stats_value);
            xmlrpc_DECREF(stats_value);

            break;

        case XMLRPC_UINT:
            snprintf(buffer, BUFFER_SIZE,
                     "%u", *((int*)value));
            stats_value = xmlrpc_build_value(env,
                                             "{s:s}",
                                             stats_name,
                                             buffer);
            xmlrpc_array_append_item(env, retval, stats_value);
            xmlrpc_DECREF(stats_value);

            break;

        case XMLRPC_FLOAT:
            snprintf(buffer, BUFFER_SIZE,
                     "%.3f", *((float*)value));
            stats_value = xmlrpc_build_value(env,
                                             "{s:s}",
                                             stats_name,
                                             buffer);
            xmlrpc_array_append_item(env, retval, stats_value);
            xmlrpc_DECREF(stats_value);

            break;

        case XMLRPC_DOUBLE:
            snprintf(buffer, BUFFER_SIZE,
                     "%.3f", *((double*)value));
            stats_value = xmlrpc_build_value(env,
                                             "{s:s}",
                                             stats_name,
                                             buffer);
            xmlrpc_array_append_item(env, retval, stats_value);
            xmlrpc_DECREF(stats_value);

            break;

        case XMLRPC_CHAR:
            stats_value = xmlrpc_build_value(env,
                                             "{s:s}",
                                             stats_name,
                                             (char*)value);
            xmlrpc_array_append_item(env, retval, stats_value);
            xmlrpc_DECREF(stats_value);

            break;

        case XMLRPC_INT64:
            snprintf(buffer, BUFFER_SIZE,
                     "%llu", *((uint64_t*)value));
            stats_value = xmlrpc_build_value(env,
                                             "{s:s}",
                                             stats_name,
                                             buffer);
            xmlrpc_array_append_item(env, retval, stats_value);
            xmlrpc_DECREF(stats_value);

            break;
    }

    if (retval == NULL) {
        xmlrpc_env_set_fault(env,
                             XMLRPC_INVALID_DATA_ERROR_CODE,
                             XMLRPC_INVALID_DATA_ERROR_MSG);
    }

    return retval;
}