diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2014-07-10 10:17:23 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2014-07-10 10:20:47 +0300 |
commit | 9d4a43fa32bf807a27d445820aa8e535aaf7410a (patch) | |
tree | 944fd1c56c937ccba693216b559fc91c8308b541 | |
parent | 131b6ab56cbec838346fd493f3fe96438e3b58e7 (diff) | |
download | eclat-9d4a43fa32bf807a27d445820aa8e535aaf7410a.tar.gz eclat-9d4a43fa32bf807a27d445820aa8e535aaf7410a.tar.bz2 |
Improvements to signature version 4 implementation
* lib/qaddparm.c (eclat_query_add_header): Remove leading and
trailing whitespace.
* lib/reqsign.c (querysign4): Add all custom headers to signed
headers.
Abort if EC2_QF_POST flag is set (not implemented yet).
-rw-r--r-- | lib/qaddparm.c | 14 | ||||
-rw-r--r-- | lib/reqsign.c | 49 |
2 files changed, 45 insertions, 18 deletions
diff --git a/lib/qaddparm.c b/lib/qaddparm.c index e1e339a..7864959 100644 --- a/lib/qaddparm.c +++ b/lib/qaddparm.c @@ -74,6 +74,18 @@ eclat_query_add_header(struct ec2_query *q, const char *name, const char *value) } ent = grecs_malloc(sizeof(*ent)); ent->name = grecs_strdup(name); - ent->value = value ? grecs_strdup(value) : NULL; + if (value) { + int len; + + while (*value == ' ' || *value == '\t') + ++value; + len = strlen(value); + while (len && (value[len-1] == ' ' || value[len-1] == '\t')) + --len; + ent->value = grecs_malloc(len + 1); + memcpy(ent->value, value, len); + ent->value[len] = 0; + } else + ent->value = NULL; grecs_list_append(q->headers, ent); } diff --git a/lib/reqsign.c b/lib/reqsign.c index 774f69b..397f6c8 100644 --- a/lib/reqsign.c +++ b/lib/reqsign.c @@ -156,10 +156,10 @@ querysign4(struct ec2_query *req, char *secret) const char *verb; char tsbuf[22]; time_t t; - char const *p; + char *p; char const *payload; - unsigned char *plhash = NULL; - size_t plsize = 0; + char *hashstr = NULL; + size_t hashsize = 0; char *string_to_sign; static char algostr[] = "AWS4-HMAC-SHA256"; static char termstr[] = "aws4_request"; @@ -170,6 +170,7 @@ querysign4(struct ec2_query *req, char *secret) struct sha256_ctx ctx; char *service; size_t service_len; + struct grecs_list_entry *ep; service = req->endpoint; service_len = strcspn(service, "."); @@ -194,12 +195,19 @@ querysign4(struct ec2_query *req, char *secret) grecs_txtacc_grow_char(acc, 0); credential = grecs_txtacc_finish(acc, 0); + eclat_query_add_header(req, "Host", req->endpoint); + /* Signed headers */ - grecs_txtacc_grow_string(acc, "host"); + for (ep = req->headers->head; ep; ep = ep->next) { + struct ec2_param *param = ep->data; + for (p = param->name; *p; p++) + grecs_txtacc_grow_char(acc, tolower(*p)); + if (ep->next) + grecs_txtacc_grow_char(acc, ';'); + } grecs_txtacc_grow_char(acc, 0); signed_headers = grecs_txtacc_finish(acc, 0); - - eclat_query_add_header(req, "Host", req->endpoint); + if (!(req->flags & EC2_QF_POST)) { eclat_query_add_param(req, "X-Amz-Algorithm", algostr); eclat_query_add_param(req, "X-Amz-Date", tsbuf); @@ -244,18 +252,25 @@ querysign4(struct ec2_query *req, char *secret) grecs_txtacc_grow_char(acc, '\n'); /* CanonicalHeaders */ - grecs_txtacc_grow_string(acc, "host:"); - grecs_txtacc_grow_string(acc, req->endpoint); - grecs_txtacc_grow_char(acc, '\n'); + for (ep = req->headers->head; ep; ep = ep->next) { + struct ec2_param *param = ep->data; + for (p = param->name; *p; p++) + grecs_txtacc_grow_char(acc, tolower(*p)); + grecs_txtacc_grow_char(acc, ':'); + grecs_txtacc_grow_string(acc, param->value); + grecs_txtacc_grow_char(acc, '\n'); + } /* end of headers */ grecs_txtacc_grow_char(acc, '\n'); /* Signed Headers */ grecs_txtacc_grow_string(acc, signed_headers); grecs_txtacc_grow_char(acc, '\n'); /* Payload hash */ - if (req->flags & EC2_QF_POST) - /* FIXME: payload = req->query */; - else + if (req->flags & EC2_QF_POST) { + /* FIXME: payload = req->query */ + err("%s:%d: POST is not yet implemented", __FILE__, __LINE__); + abort(); + } else payload = ""; sha256_init_ctx(&ctx); @@ -263,9 +278,9 @@ querysign4(struct ec2_query *req, char *secret) sha256_finish_ctx(&ctx, digest); eclat_hex_encode((unsigned char *)digest, sizeof(digest), - &plhash, &plsize); - grecs_txtacc_grow(acc, plhash, plsize); - free(plhash); + &hashstr, &hashsize); + grecs_txtacc_grow(acc, hashstr, hashsize); + free(hashstr); grecs_txtacc_grow_char(acc, 0); canonical_req = grecs_txtacc_finish(acc, 0); @@ -274,7 +289,7 @@ querysign4(struct ec2_query *req, char *secret) sha256_process_bytes(canonical_req, strlen(canonical_req), &ctx); sha256_finish_ctx(&ctx, digest); eclat_hex_encode((unsigned char *)digest, sizeof(digest), - &canonical_req, &plsize); + &canonical_req, &hashsize); /* Create a string to sign */ grecs_txtacc_grow_string(acc, algostr); @@ -316,7 +331,7 @@ querysign4(struct ec2_query *req, char *secret) digest, sizeof(digest), digest); eclat_hex_encode((unsigned char *)digest, sizeof(digest), - &signature, &plsize); + &signature, &hashsize); if (req->flags & EC2_QF_POST) { /* Build authorization header */ |