aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2015-01-19 11:26:48 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2015-01-19 11:35:21 +0200
commit4d1258de786a83888d123f4e8f791f1ad6ecf605 (patch)
treee172edcda699af4b7db72f42e30f4399866b339b /src
parent0766417065bfec9747bf0f41f9b68c27e378f817 (diff)
downloadeclat-4d1258de786a83888d123f4e8f791f1ad6ecf605.tar.gz
eclat-4d1258de786a83888d123f4e8f791f1ad6ecf605.tar.bz2
Initial support for IAM
* NEWS: Update. * doc/eclat.1man: Update. * lib/.gitignore: Update. * lib/Makefile.am (libeclat_a_SOURCES): Add new files. * lib/json.h: New file. * lib/jsongrm.y: New file. * lib/jsonlex.l: New file. * lib/yytrans: New file. * lib/libeclat.h (ec2_query) <token>: New member (eclat_query_create): Change signature. * lib/qcreat.c (eclat_query_create): Take security token as 5th argument. * lib/reqsign.c (querysign2): Add security token. * src/cmdline.opt: Update copyright years * src/ec2map.c (ec2_map_get): Pass security token to eclat_query_create. * src/eclat.c (security_token): New variable. (eclat_do_command): Pass security token to eclat_query_create. (main): Get authentication credentials from the instance store, if not found in the access file. * src/eclat.h (security_token): New extern. (eclat_get_instance_creds): New proto. * src/util.c (eclat_get_instance_zone): Use json parser. (eclat_get_instance_creds): New function. * tests/Makefile.am (noinst_PROGRAMS): add tjson * tests/tjson.c: New file.
Diffstat (limited to 'src')
-rw-r--r--src/accfile.c2
-rw-r--r--src/cmdline.opt4
-rw-r--r--src/ec2map.c2
-rw-r--r--src/eclat.c17
-rw-r--r--src/eclat.h4
-rw-r--r--src/util.c96
6 files changed, 86 insertions, 39 deletions
diff --git a/src/accfile.c b/src/accfile.c
index 3b06582..84a786b 100644
--- a/src/accfile.c
+++ b/src/accfile.c
@@ -144,7 +144,7 @@ get_access_creds(const char *id, char **access_key_ptr, char **secret_key_ptr)
int i;
glob_t g;
int rc = 1;
-
+
if (!access_file_name) {
debug(ECLAT_DEBCAT_MAIN, 1, ("no access file given"));
return 1;
diff --git a/src/cmdline.opt b/src/cmdline.opt
index 073b7b7..665ec0e 100644
--- a/src/cmdline.opt
+++ b/src/cmdline.opt
@@ -1,5 +1,5 @@
/* This file is part of Eclat.
- Copyright (C) 2012-2014 Sergey Poznyakoff.
+ Copyright (C) 2012-2015 Sergey Poznyakoff.
Eclat is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -58,7 +58,7 @@ OPTIONS_BEGIN("eclat",
[<COMMAND [COMMAND-OPTIONS...]>],
[<gnu>],
[<nopermute>],
- [<copyright_year=2012, 2013>],
+ [<copyright_year=2012-2015>],
[<copyright_holder=Sergey Poznyakoff>],[<nopermute>])
GROUP(Selecting program mode)
diff --git a/src/ec2map.c b/src/ec2map.c
index eb1d37b..03c3016 100644
--- a/src/ec2map.c
+++ b/src/ec2map.c
@@ -147,7 +147,7 @@ ec2_map_get(int dbg, int dir, void *data, const char *key, char **return_value)
int rc;
q = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0, endpoint, "/",
- region_name, access_key);
+ region_name, access_key, security_token);
eclat_query_add_param(q, "Action", map->action);
env[0] = "key";
diff --git a/src/eclat.c b/src/eclat.c
index 88592d2..5bbe7c4 100644
--- a/src/eclat.c
+++ b/src/eclat.c
@@ -26,6 +26,7 @@ char *endpoint = "ec2.amazonaws.com";
char *signature_version = "2";
char *access_key;
char *secret_key;
+char *security_token;
char *region_name;
int use_ssl;
int ssl_verify_peer = 1;
@@ -645,7 +646,8 @@ eclat_do_command(eclat_command_env_t *env, struct eclat_command *command,
if (!(command->flags & CMD_NOQRY)) {
env->query = eclat_query_create(use_ssl ? EC2_QF_HTTPS : 0,
endpoint, "/",
- region_name, access_key);
+ region_name, access_key,
+ security_token);
}
if (command->tag)
@@ -769,9 +771,16 @@ main(int argc, char **argv)
"cannot find endpoint for region %s", region_name);
if (!secret_key) {
- if (get_access_creds(access_key, &access_key, &secret_key))
- die(EX_UNAVAILABLE,
- "cannot find authentication credentials");
+ if (get_access_creds(access_key, &access_key, &secret_key)) {
+ if (!access_key)
+ die(EX_UNAVAILABLE,
+ "cannot find authentication credentials");
+ else
+ eclat_get_instance_creds(access_key,
+ &access_key,
+ &secret_key,
+ &security_token);
+ }
}
debug(ECLAT_DEBCAT_MAIN, 1, ("using access key %s", access_key));
diff --git a/src/eclat.h b/src/eclat.h
index b9c90ba..d3c0e8d 100644
--- a/src/eclat.h
+++ b/src/eclat.h
@@ -50,6 +50,7 @@ extern char *region_name;
extern char *access_file_name;
extern char *access_key;
extern char *secret_key;
+extern char *security_token;
extern char *format_file;
extern int translation_enabled;
extern char *custom_map;
@@ -173,6 +174,9 @@ void describe_query_update(eclat_command_env_t *env, int argc, char **argv,
int eclat_send_query(CURL *curl, struct ec2_query *q);
char *eclat_get_instance_zone(void);
+void eclat_get_instance_creds(char *id,
+ char **access_key_ptr, char **secret_key_ptr,
+ char **token_ptr);
int eclat_actcmp(const char *a, const char *b);
diff --git a/src/util.c b/src/util.c
index f70f70a..88e3465 100644
--- a/src/util.c
+++ b/src/util.c
@@ -15,6 +15,7 @@
along with Eclat. If not, see <http://www.gnu.org/licenses/>. */
#include "eclat.h"
+#include "json.h"
#include <termios.h>
#include <sys/ioctl.h>
@@ -430,41 +431,74 @@ char *
eclat_get_instance_zone()
{
char *doc;
+ struct json_object *obj, *p;
char *retval = NULL;
- struct wordsplit ws;
- size_t i;
- int lev;
doc = eclat_get_instance_meta_data(URL_INST_DOCUMENT);
-
- if (wordsplit(doc, &ws,
- WRDSF_NOVAR | WRDSF_NOCMD |
- WRDSF_SQUEEZE_DELIMS |
- WRDSF_DQUOTE)) {
- die(EX_UNAVAILABLE, "wordsplit: %s", wordsplit_strerror(&ws));
- }
+
+ obj = json_parse_string(doc, strlen(doc));
+ if (!obj)
+ die(EX_DATAERR,
+ "%s: near %s",
+ json_err_diag,
+ json_err_ptr);
free(doc);
- lev = 0;
- for (i = 0; i < ws.ws_wordc; i++) {
- if (strcmp(ws.ws_wordv[i], "{") == 0)
- ++lev;
- else if (strcmp(ws.ws_wordv[i], "}") == 0)
- --lev;
- else if (lev == 1 && strcmp(ws.ws_wordv[i], "region") == 0) {
- if (i + 2 < ws.ws_wordc &&
- strcmp(ws.ws_wordv[i+1], ":") == 0) {
- size_t len;
-
- retval = grecs_strdup(ws.ws_wordv[i+2]);
- len = strlen(retval);
- if (retval[len-1] == ',')
- retval[len-1] = 0;
- break;
- }
- }
- }
- wordsplit_free(&ws);
-
+ p = json_object_lookup(obj, "region");
+ if (p && p->type == json_string)
+ retval = grecs_strdup(p->v.s);
+ 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)
+{
+ char *url = NULL;
+ size_t 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);
+
+ 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)
+ *access_key_ptr = grecs_strdup(p->v.s);
+ else
+ err = 1;
+
+ p = json_object_lookup(obj, "SecretAccessKey");
+ if (p && p->type == json_string)
+ *secret_key_ptr = grecs_strdup(p->v.s);
+ else
+ err = 1;
+
+ p = json_object_lookup(obj, "Token");
+ if (p && p->type == json_string)
+ *token_ptr = grecs_strdup(p->v.s);
+ else
+ err = 1;
+
+ json_object_free(obj);
+
+ if (err)
+ die(EX_DATAERR, "security credentials missing");
+}

Return to:

Send suggestions and report system problems to the System administrator.