From 0c7bb2d5cb81eb6077a8907ce2049278fb8e47ce Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Thu, 22 Jan 2015 00:44:27 +0200 Subject: authentication-provider instance-store does not require role name argument * NEWS: Update. * doc/eclat.conf.5: Update. * lib/Makefile.am: Add new sources. * lib/istore.c: New file. * lib/path.c: New file. * lib/libeclat.h (path_concat) (instance_store_curl_new) (instance_store_read): New protos. * src/config.c (cb_authentication_provider): second argument is optional for instance-store type. New compound statement: instance-store. * src/eclat.h (instance_store_base_url) (instance_store_port,instance_store_document_path): (instance_store_credentials_path): New externs. * src/ispeek.c: Rewrite using new functions. * src/util.c: Likewise. --- src/util.c | 141 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 69 insertions(+), 72 deletions(-) (limited to 'src/util.c') diff --git a/src/util.c b/src/util.c index 88e3465..9220a11 100644 --- a/src/util.c +++ b/src/util.c @@ -367,117 +367,113 @@ canonattrname(char **attrs, const char *arg, char *delim, size_t *plen) } return NULL; } - -static size_t -get_meta_data_cb(void *ptr, size_t size, size_t nmemb, void *data) -{ - size_t realsize = size * nmemb; - char *v; - - if (debug_level(ECLAT_DEBCAT_MAIN) >= 10) - debug_printf("Got %*.*s", realsize, realsize, ptr); - - v = grecs_malloc(realsize + 1); - memcpy(v, ptr, realsize); - v[realsize] = 0; - *(char**)data = v; - return realsize; -} - -char * -eclat_get_instance_meta_data(char *url) + +char *instance_store_base_url = "http://169.254.169.254/latest"; +unsigned short instance_store_port; +char *instance_store_document_path = "dynamic/instance-identity/document"; +char *instance_store_credentials_path = "meta-data/iam/security-credentials"; + +static CURL * +get_curl(struct grecs_txtacc *acc) { CURLcode res; - CURL *curl = curl_easy_init(); - char *retval = NULL; - long http_resp; - - if (!curl) - die(EX_UNAVAILABLE, "curl_easy_init failed"); + CURL *curl = instance_store_curl_new(acc); - if (debug_level(ECLAT_DEBCAT_CURL)) { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - if (debug_level(ECLAT_DEBCAT_CURL) > 1) - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, - eclat_trace_fun); - } - - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, get_meta_data_cb); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &retval); - - curl_easy_setopt(curl, CURLOPT_URL, url); - - res = curl_easy_perform(curl); - - if (res != CURLE_OK) - die(EX_UNAVAILABLE, "CURL: %s", curl_easy_strerror(res)); - - res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp); - if (res != CURLE_OK) - die(EX_UNAVAILABLE, "CURL: %s", curl_easy_strerror(res)); - - if (http_resp != 200) - die(EX_UNAVAILABLE, "CURL: unexpected error code %3ld", res); - - curl_easy_cleanup(curl); - - return retval; + eclat_set_curl_trace(curl, debug_level(ECLAT_DEBCAT_CURL)); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + if (instance_store_port) + curl_easy_setopt(curl, CURLOPT_PORT, + (long) instance_store_port); + return curl; } -#define URL_INST_DOCUMENT\ - "http://169.254.169.254/latest/dynamic/instance-identity/document" - char * eclat_get_instance_zone() { char *doc; struct json_object *obj, *p; char *retval = NULL; - - doc = eclat_get_instance_meta_data(URL_INST_DOCUMENT); - + CURL *curl; + char *url; + struct grecs_txtacc *acc; + + acc = grecs_txtacc_create(); + curl = get_curl(acc); + url = path_concat(instance_store_base_url, + instance_store_document_path); + if (instance_store_read(url, curl)) + doc = NULL; + else { + grecs_txtacc_grow_char(acc, 0); + doc = grecs_txtacc_finish(acc, 0); + } + free(url); + curl_easy_cleanup(curl); + if (!doc) + return NULL; obj = json_parse_string(doc, strlen(doc)); if (!obj) die(EX_DATAERR, "%s: near %s", json_err_diag, json_err_ptr); - free(doc); p = json_object_lookup(obj, "region"); if (p && p->type == json_string) retval = grecs_strdup(p->v.s); + grecs_txtacc_free(acc); json_object_free(obj); return retval; } -#define URL_INST_CREDS\ - "http://169.254.169.254/latest/meta-data/iam/security-credentials/" - void eclat_get_instance_creds(char *id, char **access_key_ptr, char **secret_key_ptr, char **token_ptr) { + CURL *curl; char *url = NULL; - size_t s; + char *s; char *doc; struct json_object *obj, *p; int err = 0; - - s = sizeof(URL_INST_CREDS) + strlen(id); - url = grecs_malloc(s); - strcpy(url, URL_INST_CREDS); - strcat(url, id); - - doc = eclat_get_instance_meta_data(url); - + struct grecs_txtacc *acc; + + acc = grecs_txtacc_create(); + curl = get_curl(acc); + url = path_concat(instance_store_base_url, + instance_store_credentials_path); + if (id) { + s = url; + url = path_concat(s, id); + free(s); + } + if (instance_store_read(url, curl)) + die(EX_UNAVAILABLE, "url %s: not found ", url); + else { + grecs_txtacc_grow_char(acc, 0); + doc = grecs_txtacc_finish(acc, 0); + } + if (!id) { + size_t len = strcspn(doc, "\r\n"); + doc[len] = 0; + s = url; + url = path_concat(s, doc); + free(s); + if (instance_store_read(url, curl)) + die(EX_UNAVAILABLE, "url %s: not found ", url); + else { + grecs_txtacc_grow_char(acc, 0); + doc = grecs_txtacc_finish(acc, 0); + } + } + free(url); + obj = json_parse_string(doc, strlen(doc)); if (!obj) die(EX_DATAERR, "%s: near %s", json_err_diag, json_err_ptr); - free(doc); p = json_object_lookup(obj, "AccessKeyId"); if (p && p->type == json_string) @@ -497,6 +493,7 @@ eclat_get_instance_creds(char *id, char **access_key_ptr, char **secret_key_ptr, else err = 1; + grecs_txtacc_free(acc); json_object_free(obj); if (err) -- cgit v1.2.1