Esempio n. 1
0
/**
 * Activate an account on the server.
 *
 * @param LP1  Password hash for the account
 */
tABC_CC ABC_LoginServerActivate(const Lobby &lobby,
                                tABC_U08Buf LP1,
                                tABC_Error *pError)
{

    tABC_CC cc = ABC_CC_Ok;

    HttpReply reply;
    std::string url = ABC_SERVER_ROOT "/" ABC_SERVER_ACCOUNT_ACTIVATE;
    ServerReplyJson replyJson;
    char *szPost    = NULL;
    json_t *pJSON_Root = NULL;

    // create the post data
    pJSON_Root = json_pack("{ssss}",
        ABC_SERVER_JSON_L1_FIELD, base64Encode(lobby.authId()).c_str(),
        ABC_SERVER_JSON_LP1_FIELD, base64Encode(LP1).c_str());
    szPost = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_COMPACT);

    // send the command
    ABC_CHECK_NEW(AirbitzRequest().post(reply, url, szPost));

    // decode the result
    ABC_CHECK_NEW(replyJson.decode(reply.body));
    ABC_CHECK_NEW(replyJson.ok());

exit:
    ABC_FREE_STR(szPost);
    if (pJSON_Root)     json_decref(pJSON_Root);

    return cc;
}
Esempio n. 2
0
/**
 * Changes the password for an account on the server.
 *
 * This function sends information to the server to change the password for an account.
 * Either the old LP1 or LRA1 can be used for authentication.
 *
 * @param oldLP1 Old password hash for the account (if this is empty, LRA1 is used instead)
 * @param LRA1   LRA1 for the account (used if oldP1 is empty)
 */
tABC_CC ABC_LoginServerChangePassword(const Lobby &lobby,
                                      tABC_U08Buf oldLP1,
                                      tABC_U08Buf newLP1,
                                      tABC_U08Buf newLRA1,
                                      const CarePackage &carePackage,
                                      const LoginPackage &loginPackage,
                                      tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;

    HttpReply reply;
    std::string url = ABC_SERVER_ROOT "/" ABC_SERVER_CHANGE_PASSWORD_PATH;
    ServerReplyJson replyJson;
    char *szPost    = NULL;
    std::string carePackageStr;
    std::string loginPackageStr;
    json_t *pJSON_OldLRA1   = NULL;
    json_t *pJSON_NewLRA1   = NULL;
    json_t *pJSON_Root = NULL;

    ABC_CHECK_NULL_BUF(oldLP1);
    ABC_CHECK_NULL_BUF(newLP1);

    ABC_CHECK_NEW(carePackage.encode(carePackageStr));
    ABC_CHECK_NEW(loginPackage.encode(loginPackageStr));

    // Encode those:
    pJSON_Root = json_pack("{ss, ss, ss, ss, ss}",
        ABC_SERVER_JSON_L1_FIELD,      base64Encode(lobby.authId()).c_str(),
        ABC_SERVER_JSON_LP1_FIELD,     base64Encode(oldLP1).c_str(),
        ABC_SERVER_JSON_NEW_LP1_FIELD, base64Encode(newLP1).c_str(),
        ABC_SERVER_JSON_CARE_PACKAGE_FIELD,  carePackageStr.c_str(),
        ABC_SERVER_JSON_LOGIN_PACKAGE_FIELD, loginPackageStr.c_str());

    // set up the recovery, if any:
    if (newLRA1.size())
    {
        pJSON_NewLRA1 = json_string(base64Encode(newLRA1).c_str());
        json_object_set(pJSON_Root, ABC_SERVER_JSON_NEW_LRA1_FIELD, pJSON_NewLRA1);
    }

    // create the post data
    szPost = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_COMPACT);

    // send the command
    ABC_CHECK_NEW(AirbitzRequest().post(reply, url, szPost));

    ABC_CHECK_NEW(replyJson.decode(reply.body));
    ABC_CHECK_NEW(replyJson.ok());

exit:
    ABC_FREE_STR(szPost);
    if (pJSON_OldLRA1)  json_decref(pJSON_OldLRA1);
    if (pJSON_NewLRA1)  json_decref(pJSON_NewLRA1);
    if (pJSON_Root)     json_decref(pJSON_Root);

    return cc;
}
Esempio n. 3
0
/**
 * Uploads the pin package.
 *
 * @param LP1           Login + Password hash
 * @param DID           Device Id
 * @param LPIN1         Hashed pin
 * @param szPinPackage  Pin package
 * @param szAli         auto-logout interval
 */
tABC_CC ABC_LoginServerUpdatePinPackage(const Lobby &lobby,
                                        tABC_U08Buf LP1,
                                        tABC_U08Buf DID,
                                        tABC_U08Buf LPIN1,
                                        const std::string &pinPackage,
                                        time_t ali,
                                        tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;

    HttpReply reply;
    std::string url = ABC_SERVER_ROOT "/" ABC_SERVER_PIN_PACK_UPDATE_PATH;
    ServerReplyJson replyJson;
    char *szPost         = NULL;
    json_t *pJSON_Root   = NULL;
    char szALI[DATETIME_LENGTH];

    ABC_CHECK_NULL_BUF(LP1);
    ABC_CHECK_NULL_BUF(DID);
    ABC_CHECK_NULL_BUF(LPIN1);

    // format the ali
    strftime(szALI, DATETIME_LENGTH, "%Y-%m-%dT%H:%M:%S", gmtime(&ali));

    // Encode those:
    pJSON_Root = json_pack("{ss, ss, ss, ss, ss, ss}",
        ABC_SERVER_JSON_L1_FIELD, base64Encode(lobby.authId()).c_str(),
        ABC_SERVER_JSON_LP1_FIELD, base64Encode(LP1).c_str(),
        ABC_SERVER_JSON_DID_FIELD, base64Encode(DID).c_str(),
        ABC_SERVER_JSON_LPIN1_FIELD, base64Encode(LPIN1).c_str(),
        JSON_ACCT_PIN_PACKAGE, pinPackage.c_str(),
        ABC_SERVER_JSON_ALI_FIELD, szALI);

    // create the post data
    szPost = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_COMPACT);

    // send the command
    ABC_CHECK_NEW(AirbitzRequest().post(reply, url, szPost));

    ABC_CHECK_NEW(replyJson.decode(reply.body));
    ABC_CHECK_NEW(replyJson.ok());

exit:
    ABC_FREE_STR(szPost);
    if (pJSON_Root)     json_decref(pJSON_Root);

    return cc;
}
Esempio n. 4
0
tABC_CC ABC_LoginServerGetPinPackage(tABC_U08Buf DID,
                                     tABC_U08Buf LPIN1,
                                     char **szPinPackage,
                                     tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;

    HttpReply reply;
    std::string url = ABC_SERVER_ROOT "/" ABC_SERVER_PIN_PACK_GET_PATH;
    ServerReplyJson replyJson;
    json_t  *pJSON_Value    = NULL;
    json_t  *pJSON_Root     = NULL;
    char    *szPost         = NULL;

    ABC_CHECK_NULL_BUF(DID);
    ABC_CHECK_NULL_BUF(LPIN1);

    pJSON_Root = json_pack("{ss, ss}",
        ABC_SERVER_JSON_DID_FIELD, base64Encode(DID).c_str(),
        ABC_SERVER_JSON_LPIN1_FIELD, base64Encode(LPIN1).c_str());

    szPost = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_COMPACT);

    // send the command
    ABC_CHECK_NEW(AirbitzRequest().post(reply, url, szPost));

    // Check the result
    ABC_CHECK_NEW(replyJson.decode(reply.body));
    ABC_CHECK_NEW(replyJson.ok());

    // get the results field
    pJSON_Value = replyJson.results().get();
    ABC_CHECK_ASSERT((pJSON_Value && json_is_object(pJSON_Value)), ABC_CC_JSONError, "Error parsing server JSON pin package results");

    // get the pin_package field
    pJSON_Value = json_object_get(pJSON_Value, JSON_ACCT_PIN_PACKAGE);
    ABC_CHECK_ASSERT((pJSON_Value && json_is_string(pJSON_Value)), ABC_CC_JSONError, "Error pin package JSON results");

    // copy the value
    ABC_STRDUP(*szPinPackage, json_string_value(pJSON_Value));

exit:
    if (pJSON_Root)     json_decref(pJSON_Root);
    ABC_FREE_STR(szPost);

    return cc;
}
Esempio n. 5
0
/**
 * Creates an account on the server.
 *
 * This function sends information to the server to create an account.
 * If the account was created, ABC_CC_Ok is returned.
 * If the account already exists, ABC_CC_AccountAlreadyExists is returned.
 *
 * @param LP1  Password hash for the account
 */
tABC_CC ABC_LoginServerCreate(const Lobby &lobby,
                              tABC_U08Buf LP1,
                              const CarePackage &carePackage,
                              const LoginPackage &loginPackage,
                              const char *szRepoAcctKey,
                              tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;

    HttpReply reply;
    std::string url = ABC_SERVER_ROOT "/" ABC_SERVER_ACCOUNT_CREATE_PATH;
    ServerReplyJson replyJson;
    char *szPost    = NULL;
    std::string carePackageStr;
    std::string loginPackageStr;
    json_t *pJSON_Root = NULL;

    ABC_CHECK_NULL_BUF(LP1);

    ABC_CHECK_NEW(carePackage.encode(carePackageStr));
    ABC_CHECK_NEW(loginPackage.encode(loginPackageStr));

    // create the post data
    pJSON_Root = json_pack("{ssssssssss}",
        ABC_SERVER_JSON_L1_FIELD, base64Encode(lobby.authId()).c_str(),
        ABC_SERVER_JSON_LP1_FIELD, base64Encode(LP1).c_str(),
        ABC_SERVER_JSON_CARE_PACKAGE_FIELD, carePackageStr.c_str(),
        ABC_SERVER_JSON_LOGIN_PACKAGE_FIELD, loginPackageStr.c_str(),
        ABC_SERVER_JSON_REPO_FIELD, szRepoAcctKey);
    szPost = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_COMPACT);

    // send the command
    ABC_CHECK_NEW(AirbitzRequest().post(reply, url, szPost));

    // decode the result
    ABC_CHECK_NEW(replyJson.decode(reply.body));
    ABC_CHECK_NEW(replyJson.ok());

exit:
    ABC_FREE_STR(szPost);
    if (pJSON_Root)     json_decref(pJSON_Root);

    return cc;
}
Esempio n. 6
0
/**
 * Serializes a LoginPackage object to a JSON string.
 */
tABC_CC ABC_LoginPackageEncode(tABC_LoginPackage *pSelf,
                               char **pszLoginPackage,
                               tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;
    json_t  *pJSON_Root     = NULL;

    // Build the main body:
    pJSON_Root = json_object();
    ABC_CHECK_NULL(pJSON_Root);

    // Write master key:
    if (pSelf->EMK_LP2)
    {
        ABC_CHECK_JSON(json_object_set(pJSON_Root, JSON_ACCT_EMK_LP2_FIELD, pSelf->EMK_LP2));
    }
    if (pSelf->EMK_LRA3)
    {
        ABC_CHECK_JSON(json_object_set(pJSON_Root, JSON_ACCT_EMK_LRA3_FIELD, pSelf->EMK_LRA3));
    }

    // Write sync key:
    ABC_CHECK_JSON(json_object_set(pJSON_Root, JSON_ACCT_ESYNCKEY_FIELD, pSelf->ESyncKey));

    // Write server keys:
    if (pSelf->ELP1)
    {
        ABC_CHECK_JSON(json_object_set(pJSON_Root, JSON_ACCT_ELP1_FIELD, pSelf->ELP1));
    }
    if (pSelf->ELRA1)
    {
        ABC_CHECK_JSON(json_object_set(pJSON_Root, JSON_ACCT_ELRA1_FIELD, pSelf->ELRA1));
    }

    // Write out:
    *pszLoginPackage = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_INDENT(4) | JSON_PRESERVE_ORDER);
    ABC_CHECK_NULL(*pszLoginPackage);

exit:
    if (pJSON_Root)     json_decref(pJSON_Root);

    return cc;
}
Esempio n. 7
0
tABC_CC ABC_LoginServerOtpRequest(const char *szUrl,
                                  const Lobby &lobby,
                                  tABC_U08Buf LP1,
                                  JsonPtr *results,
                                  tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;

    HttpReply reply;
    ServerReplyJson replyJson;
    char *szPost    = NULL;
    json_t *pJSON_Root = NULL;

    // create the post data
    pJSON_Root = json_pack("{ss}",
        ABC_SERVER_JSON_L1_FIELD, base64Encode(lobby.authId()).c_str());
    // If there is a LP1 provided
    if (LP1.data())
    {
        json_object_set_new(pJSON_Root, ABC_SERVER_JSON_LP1_FIELD,
            json_string(base64Encode(LP1).c_str()));
    }
    {
        auto key = lobby.otpKey();
        if (key)
            json_object_set_new(pJSON_Root, ABC_SERVER_JSON_OTP_FIELD, json_string(key->totp().c_str()));
    }
    json_object_set_new(pJSON_Root, ABC_SERVER_JSON_OTP_RESET_AUTH, json_string(gOtpResetAuth.c_str()));
    szPost = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_COMPACT);

    // send the command
    ABC_CHECK_NEW(AirbitzRequest().post(reply, szUrl, szPost));

    ABC_CHECK_NEW(replyJson.decode(reply.body));
    ABC_CHECK_NEW(replyJson.ok());
    if (results)
        *results = replyJson.results();

exit:
    ABC_FREE_STR(szPost);
    if (pJSON_Root)     json_decref(pJSON_Root);
    return cc;
}
Esempio n. 8
0
/**
 * Enables 2 Factor authentication
 *
 * @param LP1  Password hash for the account
 * @param timeout Amount of time needed for a reset to complete
 */
tABC_CC ABC_LoginServerOtpEnable(const Lobby &lobby,
                                 tABC_U08Buf LP1,
                                 const char *szOtpSecret,
                                 const long timeout,
                                 tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;

    HttpReply reply;
    std::string url = ABC_SERVER_ROOT "/otp/on";
    ServerReplyJson replyJson;
    char *szPost    = NULL;
    json_t *pJSON_Root = NULL;

    ABC_CHECK_NULL_BUF(LP1);

    // create the post data
    pJSON_Root = json_pack("{sssssssi}",
        ABC_SERVER_JSON_L1_FIELD, base64Encode(lobby.authId()).c_str(),
        ABC_SERVER_JSON_LP1_FIELD, base64Encode(LP1).c_str(),
        ABC_SERVER_JSON_OTP_SECRET_FIELD, szOtpSecret,
        ABC_SERVER_JSON_OTP_TIMEOUT, timeout);
    {
        auto key = lobby.otpKey();
        if (key)
            json_object_set_new(pJSON_Root, ABC_SERVER_JSON_OTP_FIELD, json_string(key->totp().c_str()));
    }

    szPost = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_COMPACT);

    // send the command
    ABC_CHECK_NEW(AirbitzRequest().post(reply, url, szPost));

    ABC_CHECK_NEW(replyJson.decode(reply.body));
    ABC_CHECK_NEW(replyJson.ok());

exit:
    ABC_FREE_STR(szPost);
    if (pJSON_Root)     json_decref(pJSON_Root);

    return cc;
}
Esempio n. 9
0
/**
 * Serializes a CarePackage object to a JSON string.
 */
tABC_CC ABC_CarePackageEncode(tABC_CarePackage *pSelf,
                              char **pszCarePackage,
                              tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;
    json_t *pJSON_Root  = NULL;
    json_t *pJSON_SNRP2 = NULL;
    json_t *pJSON_SNRP3 = NULL;
    json_t *pJSON_SNRP4 = NULL;

    // Build the SNRP's:
    ABC_CHECK_RET(ABC_CryptoCreateJSONObjectSNRP(pSelf->pSNRP2, &pJSON_SNRP2, pError));
    ABC_CHECK_RET(ABC_CryptoCreateJSONObjectSNRP(pSelf->pSNRP3, &pJSON_SNRP3, pError));
    ABC_CHECK_RET(ABC_CryptoCreateJSONObjectSNRP(pSelf->pSNRP4, &pJSON_SNRP4, pError));

    // Build the main body:
    pJSON_Root = json_pack("{s:O, s:O, s:O}",
        JSON_ACCT_SNRP2_FIELD, pJSON_SNRP2,
        JSON_ACCT_SNRP3_FIELD, pJSON_SNRP3,
        JSON_ACCT_SNRP4_FIELD, pJSON_SNRP4);
    ABC_CHECK_NULL(pJSON_Root);

    // Build the ERQ, if any:
    if (pSelf->ERQ)
    {
        ABC_CHECK_JSON(json_object_set(pJSON_Root, JSON_ACCT_ERQ_FIELD, pSelf->ERQ));
    }

    // Write out:
    *pszCarePackage = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_INDENT(4) | JSON_PRESERVE_ORDER);
    ABC_CHECK_NULL(*pszCarePackage);

exit:
    if (pJSON_Root)     json_decref(pJSON_Root);
    if (pJSON_SNRP2)    json_decref(pJSON_SNRP2);
    if (pJSON_SNRP3)    json_decref(pJSON_SNRP3);
    if (pJSON_SNRP4)    json_decref(pJSON_SNRP4);

    return cc;
}
Esempio n. 10
0
/**
 * Creates the json package with a single field and its int value
 */
tABC_CC ABC_UtilCreateIntJSONString(int        value,
                                    const char *szFieldName,
                                    char       **pszJSON,
                                    tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;

    json_t *pJSON_Root = NULL;

    ABC_CHECK_NULL(szFieldName);
    ABC_CHECK_NULL(pszJSON);

    // create the jansson object
    pJSON_Root = json_pack("{si}", szFieldName, value);

    *pszJSON = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_INDENT(4) | JSON_PRESERVE_ORDER);

exit:
    if (pJSON_Root) json_decref(pJSON_Root);

    return cc;
}
Esempio n. 11
0
static
tABC_CC ABC_WalletServerRepoPost(const Lobby &lobby,
                                 tABC_U08Buf LP1,
                                 const char *szWalletAcctKey,
                                 const char *szPath,
                                 tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;

    HttpReply reply;
    std::string url = ABC_SERVER_ROOT "/" + std::string(szPath);
    ServerReplyJson replyJson;
    char *szPost    = NULL;
    json_t *pJSON_Root = NULL;

    ABC_CHECK_NULL_BUF(LP1);

    // create the post data
    pJSON_Root = json_pack("{ssssss}",
        ABC_SERVER_JSON_L1_FIELD, base64Encode(lobby.authId()).c_str(),
        ABC_SERVER_JSON_LP1_FIELD, base64Encode(LP1).c_str(),
        ABC_SERVER_JSON_REPO_WALLET_FIELD, szWalletAcctKey);
    szPost = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_COMPACT);

    // send the command
    ABC_CHECK_NEW(AirbitzRequest().post(reply, url, szPost));

    ABC_CHECK_NEW(replyJson.decode(reply.body));
    ABC_CHECK_NEW(replyJson.ok());

exit:
    ABC_FREE_STR(szPost);
    if (pJSON_Root)     json_decref(pJSON_Root);

    return cc;
}
Esempio n. 12
0
tABC_CC ABC_LoginServerOtpPending(std::list<DataChunk> users, std::list<bool> &isPending, tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;

    HttpReply reply;
    std::string url = ABC_SERVER_ROOT "/otp/pending/check";
    ServerReplyJson replyJson;
    JsonArray arrayJson;
    json_t *pJSON_Root = NULL;
    char *szPost = NULL;
    std::map<std::string, bool> userMap;
    std::list<std::string> usersEncoded;

    std::string param;
    for (const auto &u : users)
    {
        std::string username = base64Encode(u);
        param += (username + ",");
        userMap[username] = false;
        usersEncoded.push_back(username);
    }

    // create the post data
    pJSON_Root = json_pack("{ss}", "l1s", param.c_str());
    szPost = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_COMPACT);

    // send the command
    ABC_CHECK_NEW(AirbitzRequest().post(reply, url, szPost));

    ABC_CHECK_NEW(replyJson.decode(reply.body));
    ABC_CHECK_NEW(replyJson.ok());

    arrayJson = replyJson.results();
    if (arrayJson)
    {
        size_t rows = arrayJson.size();
        for (size_t i = 0; i < rows; i++)
        {
            json_t *pJSON_Row = arrayJson[i].get();
            ABC_CHECK_ASSERT((pJSON_Row && json_is_object(pJSON_Row)), ABC_CC_JSONError, "Error parsing JSON array element object");

            json_t *pJSON_Value = json_object_get(pJSON_Row, "login");
            ABC_CHECK_ASSERT((pJSON_Value && json_is_string(pJSON_Value)), ABC_CC_JSONError, "Error otp/pending/login JSON");
            std::string username(json_string_value(pJSON_Value));

            pJSON_Value = json_object_get(pJSON_Row, ABC_SERVER_JSON_OTP_PENDING);
            ABC_CHECK_ASSERT((pJSON_Value && json_is_boolean(pJSON_Value)), ABC_CC_JSONError, "Error otp/pending/pending JSON");
            if (json_is_true(pJSON_Value))
            {
                userMap[username] = json_is_true(pJSON_Value);;
            }
        }
    }
    isPending.clear();
    for (auto &username: usersEncoded) {
        isPending.push_back(userMap[username]);
    }

exit:
    ABC_FREE_STR(szPost);
    if (pJSON_Root)      json_decref(pJSON_Root);

    return cc;
}
Esempio n. 13
0
/**
 * Helper function for getting CarePackage or LoginPackage.
 */
static
tABC_CC ABC_LoginServerGetString(const Lobby &lobby, tABC_U08Buf LP1, tABC_U08Buf LRA1,
                                 const char *szURL, const char *szField, char **szResponse, tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;

    HttpReply reply;
    ServerReplyJson replyJson;
    json_t  *pJSON_Value    = NULL;
    json_t  *pJSON_Root     = NULL;
    char    *szPost         = NULL;

    // create the post data with or without LP1
    if (LP1.data() == NULL && LRA1.data() == NULL)
    {
        pJSON_Root = json_pack("{ss}",
            ABC_SERVER_JSON_L1_FIELD, base64Encode(lobby.authId()).c_str());
    }
    else
    {
        if (LP1.data() == NULL)
        {
            pJSON_Root = json_pack("{ssss}",
                ABC_SERVER_JSON_L1_FIELD, base64Encode(lobby.authId()).c_str(),
                ABC_SERVER_JSON_LRA1_FIELD, base64Encode(LRA1).c_str());
        }
        else
        {
            pJSON_Root = json_pack("{ssss}",
                ABC_SERVER_JSON_L1_FIELD, base64Encode(lobby.authId()).c_str(),
                ABC_SERVER_JSON_LP1_FIELD, base64Encode(LP1).c_str());
        }
    }
    {
        auto key = lobby.otpKey();
        if (key)
            json_object_set_new(pJSON_Root, ABC_SERVER_JSON_OTP_FIELD, json_string(key->totp().c_str()));
    }
    szPost = ABC_UtilStringFromJSONObject(pJSON_Root, JSON_COMPACT);

    // send the command
    ABC_CHECK_NEW(AirbitzRequest().post(reply, szURL, szPost));

    // Check the results, and store json if successful
    ABC_CHECK_NEW(replyJson.decode(reply.body));
    ABC_CHECK_NEW(replyJson.ok());

    // get the care package
    pJSON_Value = replyJson.results().get();
    ABC_CHECK_ASSERT((pJSON_Value && json_is_object(pJSON_Value)), ABC_CC_JSONError, "Error parsing server JSON care package results");

    pJSON_Value = json_object_get(pJSON_Value, szField);
    ABC_CHECK_ASSERT((pJSON_Value && json_is_string(pJSON_Value)), ABC_CC_JSONError, "Error care package JSON results");
    ABC_STRDUP(*szResponse, json_string_value(pJSON_Value));

exit:
    if (pJSON_Root)     json_decref(pJSON_Root);
    ABC_FREE_STR(szPost);

    return cc;
}