static void linda_store_handler(void *p1, const uuid *u, const void *_s, int len) { linda *l = (linda*)p1; const char *s = (const char*)_s; if (len > 0) // add { json *j = json_open(s); json *j1 = json_get_object(j); json *jid = json_find(j1, LINDA_ID); if (!jid) return; if (json_is_integer(jid)) { long long k = json_get_integer(jid); if (l->sl && !l->is_int) { printf("linda_store_handler: expected integer id\n"); return; } if (!l->sl) { l->sl = sb_int_uuid_create2(); l->is_int = 1; } sb_int_uuid_set(l->sl, k, u); } else if (json_is_string(jid)) { const char *k = json_get_string(jid); if (l->sl && !l->is_string) { printf("linda_store_handler: expected string id\n"); return; } if (!l->sl) { l->sl = sb_string_uuid_create2(); l->is_string = 1; } sb_string_uuid_set(l->sl, k, u); } json_close(j); } else if (len < 0) // remove (with hint) { json *j = json_open(s); json *j1 = json_get_object(j); json *jid = json_find(j1, LINDA_ID); if (!jid) return; if (json_is_integer(jid)) { long long k = json_get_integer(jid); if (l->sl && !l->is_int) { printf("linda_out: expected integer id\n"); return; } if (!l->sl) { l->sl = sb_int_uuid_create2(); l->is_int = 1; } sb_int_uuid_erase(l->sl, k, u); } else if (json_is_string(jid)) { const char *k = json_get_string(jid); if (l->sl && !l->is_string) { printf("linda_out: expected string id\n"); return; } if (!l->sl) { l->sl = sb_string_uuid_create2(); l->is_string = 1; } sb_string_uuid_erase(l->sl, k, u); } json_close(j); } else // remove (brute search) { sb_uuid_efface(l->sl, u); } }
static bool get_domain_records(const char *domain, domain_t **d, bool force, error_t **error) { domain_set_t *ds; bool request_success; *d = NULL; FETCH_ACCOUNT_DOMAINS(ds); request_success = TRUE; // TODO: hashtable_clear((*d)->records) if force if (!hashtable_get(ds->domains, domain, d) || !(*d)->uptodate || force) { request_t *req; json_document_t *doc; if (NULL == *d) { *d = domain_new(); hashtable_put(ds->domains, 0, domain, *d, NULL); } req = request_new(REQUEST_FLAG_SIGN, HTTP_GET, NULL, error, API_BASE_URL "/domain/zone/%s/record", domain); request_success = request_execute(req, RESPONSE_JSON, (void **) &doc, error); request_destroy(req); // result if (request_success) { Iterator it; json_value_t root; root = json_document_get_root(doc); json_array_to_iterator(&it, root); for (iterator_first(&it); request_success && iterator_is_valid(&it); iterator_next(&it)) { json_value_t v; json_document_t *doc; v = (json_value_t) iterator_current(&it, NULL); req = request_new(REQUEST_FLAG_SIGN, HTTP_GET, NULL, error, API_BASE_URL "/domain/zone/%s/record/%u", domain, json_get_integer(v)); request_success = request_execute(req, RESPONSE_JSON, (void **) &doc, error); request_destroy(req); // result parse_record((*d)->records, doc); } iterator_close(&it); json_document_destroy(doc); (*d)->uptodate = TRUE; } } return request_success ? COMMAND_SUCCESS : COMMAND_FAILURE; }
int linda_rm(hlinda *h, const char *s) { json *j = json_open(s); json *j1 = json_get_object(j); int is_int = 0, is_string = 0; const char *string_id = NULL; long long int_id = 0; uuid u; json *joid = json_find(j1, LINDA_OID); if (!joid) { json_close(j); return 0; } uuid_from_string(json_get_string(joid), &u); json *jid = json_find(j1, LINDA_ID); if (jid) { if (h->l->is_int && !json_is_integer(jid)) { printf("linda_read: expected integer id\n"); json_close(j); return 0; } else if (h->l->is_string && !json_is_string(jid)) { printf("linda_read: expected string id\n"); json_close(j); return 0; } if (json_is_integer(jid)) { int_id = json_get_integer(jid); is_int = 1; } else if (json_is_string(jid)) { string_id = json_get_string(jid); json_close(h->jquery); is_string = 1; } else { json_close(j); return 0; } } json_close(j); if (is_int) { char tmpbuf[1024]; int tmplen = sprintf(tmpbuf, "{\"%s\":%lld}\n", LINDA_ID, int_id); store_hrem2(h->hst, &u, tmpbuf, tmplen); sb_int_uuid_erase(h->l->sl, int_id, &u); } else if (is_string) { char tmpbuf[1024], tmpbuf2[1024]; json_format_string(string_id, tmpbuf2, sizeof(tmpbuf2)); int tmplen = sprintf(tmpbuf, "{\"%s\":\"%s\"}\n", LINDA_ID, tmpbuf2); store_hrem2(h->hst, &u, tmpbuf, tmplen); sb_string_uuid_erase(h->l->sl, string_id, &u); } else { store_rem(h->l->st, &u); sb_uuid_efface(h->l->sl, &u); } return 1; }
int linda_out(hlinda *h, const char *s) { if (!h) return 0; json *j = json_open(s); json *j1 = json_get_object(j); json *joid = json_find(j1, LINDA_OID); uuid u; if (joid) { uuid_from_string(json_get_string(joid), &u); } else uuid_gen(&u); json *jid = json_find(j1, LINDA_ID); if (jid) { if (json_is_integer(jid)) { long long k = json_get_integer(jid); if (h->l->sl && !h->l->is_int) { printf("linda_out: expected integer id\n"); return 0; } if (!h->l->sl) { h->l->sl = sb_int_uuid_create2(); h->l->is_int = 1; } sb_int_uuid_set(h->l->sl, k, &u); } else if (json_is_string(jid)) { const char *k = json_get_string(jid); if (h->l->sl && !h->l->is_string) { printf("linda_out: expected string id\n"); return 0; } if (!h->l->sl) { h->l->sl = sb_string_uuid_create2(); h->l->is_string = 1; } sb_string_uuid_set(h->l->sl, k, &u); } } store_hadd(h->hst, &u, s, strlen(s)); h->last_oid = u; json_close(j); return 0; }
static int linda_read(hlinda *h, const char *s, const char **buf, int rm, int nowait) { json *j = json_open(s); json *j1 = json_get_object(j); h->oid.u1 = h->oid.u2 = 0; int is_int = 0, is_string = 0; json *jid = json_find(j1, LINDA_ID); if (jid) { if (h->l->is_int && !json_is_integer(jid)) { printf("linda_read: expected integer id\n"); json_close(j); return 0; } else if (h->l->is_string && !json_is_string(jid)) { printf("linda_read: expected string id\n"); json_close(j); return 0; } if (json_is_integer(jid)) { h->int_id = json_get_integer(jid); h->jquery = json_open(s); sb_int_uuid_find(h->l->sl, h->int_id, &read_int_handler, h); json_close(h->jquery); is_int = 1; } else if (json_is_string(jid)) { h->string_id = json_get_string(jid); h->jquery = json_open(s); sb_string_uuid_find(h->l->sl, h->string_id, &read_string_handler, h); json_close(h->jquery); is_string = 1; } else { json_close(j); return 0; } } else { h->jquery = json_open(s); sb_iter(h->l->sl, &read_handler, h); json_close(h->jquery); } json_close(j); if (!h->oid.u1 && !h->oid.u2) return 0; if (rm) { if (is_int) { char tmpbuf[1024]; int tmplen = sprintf(tmpbuf, "{\"%s\":%lld}\n", LINDA_ID, h->int_id); store_hrem2(h->hst, &h->oid, tmpbuf, tmplen); sb_int_uuid_erase(h->l->sl, h->int_id, &h->oid); } else if (is_string) { char tmpbuf[1024], tmpbuf2[1024]; json_format_string(h->string_id, tmpbuf2, sizeof(tmpbuf2)); int tmplen = sprintf(tmpbuf, "{\"%s\":\"%s\"}\n", LINDA_ID, tmpbuf2); store_hrem2(h->hst, &h->oid, tmpbuf, tmplen); sb_string_uuid_erase(h->l->sl, h->string_id, &h->oid); } else { store_hrem(h->hst, &h->oid); sb_uuid_efface(h->l->sl, &h->oid); } } *buf = h->dst; return 1; }
static int read_handler(void *arg, void *k, void *v) { hlinda *h = (hlinda*)arg; uuid *u = (uuid*)v; if (!store_get(h->l->st, u, (void**)&h->dst, &h->len)) return 0; int match = 1; json *j1 = json_get_object(h->jquery); json *jdst = json_open(h->dst); json *j2 = json_get_object(jdst); size_t i, cnt = json_count(j1); for (i = 0; i < cnt; i++) { json *j1it = json_index(j1, i); const char *name = json_get_string(j1it); if (name[0] == '$') continue; json *j2it = json_find(j2, name); if (!j2it) { match = 0; continue; } if (json_is_integer(j1it)) { if (!json_is_integer(j2it)) { match = 0; break; } if (json_get_integer(j1it) != json_get_integer(j2it)) { match = 0; break; } } else if (json_is_real(j1it)) { if (!json_is_real(j2it)) { match = 0; break; } if (json_get_real(j1it) != json_get_real(j2it)) { match = 0; break; } } else if (json_is_string(j1it)) { if (!json_is_string(j2it)) { match = 0; break; } if (strcmp(json_get_string(j1it), json_get_string(j2it))) { match = 0; break; } } else if (json_is_true(j1it)) { if (!json_is_true(j2it)) { match = 0; break; } } else if (json_is_false(j1it)) { if (!json_is_false(j2it)) { match = 0; break; } } else if (json_is_null(j1it)) { if (!json_is_null(j2it)) { match = 0; break; } } } json_close(jdst); if (!match) return 1; h->oid.u1 = u->u1; h->oid.u2 = u->u2; return 0; }
/** * Get Data Key from server */ static int get_data_key(const char *token, char *masterkeyid, char *datakeyid, char *datakey) { int ret; CURL *curl; CURLcode res; char serverurl[URL_SIZE]; char recvdata[BUF_SIZE+2]; char headerstring[HEADER_SIZE]; void *jsonhandler=NULL; char *jsonmasterkeyid = NULL; char *jsondatakeyid = NULL; int timeout; char *jsonkeyencryptedbase64 = NULL; struct curl_slist* headers = NULL; size_t len; // make request header memset(headerstring, 0, HEADER_SIZE); sprintf(headerstring, "Authorization: Token %s", token); headers = curl_slist_append(headers, headerstring); // make request url memset(serverurl, 0, URL_SIZE); memset(recvdata, 0, BUF_SIZE+2); if (strlen(datakeyid) > 0) sprintf(serverurl, "http://%s/data/key/%s", fcgienc_datakeyserver, datakeyid); else sprintf(serverurl, "http://%s/data/key", fcgienc_datakeyserver); curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, serverurl); // curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFn); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)recvdata); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5); /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); log_keythread("KEY-THREAD - curl request : %s, header : %s", serverurl, headerstring); /* Check for errors */ if(res != CURLE_OK) { log_keythread("KEY-THREAD - curl failed : %s", curl_easy_strerror(res)); ret = -1; goto DATAKEY_EXIT; } } // process json response jsonhandler = json_load(recvdata); log_keythread("KEY-THREAD - curl response : %s", recvdata); // get data key id jsondatakeyid = json_get_string(jsonhandler, "key_id"); if (!jsondatakeyid) { log_keythread("KEY-THREAD - not found \"data key id\" in response : %s", recvdata); ret = -1; goto DATAKEY_EXIT; } // get master key id jsonmasterkeyid = json_get_string(jsonhandler, "master_key_id"); if (!jsonmasterkeyid) { log_keythread("KEY-THREAD - not found master key id in response : %s", recvdata); ret = -1; goto DATAKEY_EXIT; } if (strcmp(jsonmasterkeyid, masterkeyid)) { log_keythread("KEY-THREAD - unmatched master key id in old-%s : new-%s", masterkeyid, jsonmasterkeyid); len = strlen(jsonmasterkeyid); if (len > 255) len = 255; memcpy(masterkeyid, jsonmasterkeyid, len); masterkeyid[len] = 0; } // get refresh interval timeout = json_get_integer(jsonhandler, "refresh_interval"); if (timeout < 0) { log_keythread("KEY-THREAD - not found \"data key refresh_interval\" in response : %s", recvdata); ret = -1; goto DATAKEY_EXIT; } // get key encrypted base64 jsonkeyencryptedbase64 = json_get_string(jsonhandler, "key_encrypted_base64"); if (!jsonkeyencryptedbase64) { log_keythread("KEY-THREAD - not found \"key_encrypted_base64\" in response : %s", recvdata); ret = -1; goto DATAKEY_EXIT; } // store into variable len = strlen(jsondatakeyid); if (len > 255) len = 255; memcpy(datakeyid, jsondatakeyid, len); datakeyid[len] = 0; len = strlen(jsonkeyencryptedbase64); if (len > 255) len = 255; memcpy(datakey, jsonkeyencryptedbase64, len); datakey[len] = 0; ret = timeout; DATAKEY_EXIT: if (headers) curl_slist_free_all( headers ) ; if (curl) curl_easy_cleanup(curl); if (jsonhandler) json_unload(jsonhandler); return ret; }