samedi 10 octobre 2015

D AWS api authorization is not working

I'm trying to connect to AWS API in program written in D. i'm using this module: http://ift.tt/1R4QkNk

With small modification (removed vibe.d dependency, by copy paste missed 2 functions from it). All unit tests are passing. On top of it i wrote such program:

#!/usr/bin/rdmd -L-lcurl

import std.stdio;
import std.string;
import std.file;
import std.datetime;
import std.process;
import std.digest.sha;
import std.net.curl;
import std.uri;
import sigv4;


auto zone = "us-east-1";
auto service = "ec2";


void main()
{
    auto accKey = environment["AWS_ACCESS_KEY"];
    auto secKey = environment["AWS_SECRET_KEY"];

    auto currentClock = Clock.currTime;

    auto currentDate = cast(Date)currentClock;
    auto curDateStr = currentDate.toISOString;

    auto currentTime = cast(TimeOfDay)currentClock;
    auto curTimeStr = currentTime.toISOString;

    auto xamztime = curDateStr ~ "T" ~ curTimeStr ~ "Z";

    string[string] empty;

    SignableRequest r;
    r.dateString = "20110909";//curDateStr;
    r.timeStringUTC = "233600i";//curTimeStr;
    r.region = "us-east-1";//zone;
    r.service = "iam"; //service;
    r.canonicalRequest = CanonicalRequest(
                    "POST",
                    "/",
                    empty,
    //              ["action" : "DescribeInstances", "version" : "2013-10-15"],
        //          ["accept" : "*/*",
                    ["content-type" : "application/x-www-form-urlencoded; charset=utf-8",
                     "host" : service ~ ".amazonaws.com",
                     "x-amz-date" : xamztime],
                    cast(ubyte[])"Action=DescribeInstances&Version=2013-10-1");  
    auto qParm = canonicalQueryString(r.canonicalRequest.queryParameters);

    auto sigHead = canonicalHeaders(r.canonicalRequest.headers);

    auto sigStr = signableString(r);

    auto sigKey = signingKey(secKey, curDateStr, zone, service);

    auto signature = sign(sigKey, cast(ubyte[])sigStr).toHexString().toLower();

    writeln();  
    writeln(qParm);
    writeln();
    writeln(sigHead);
    writeln();
    writeln(sigStr);
    writeln();
    writeln(sigKey);
    writeln(signature);
    writeln();
    auto client = HTTP();
//  client.clearRequestHeaders;
    client.addRequestHeader("content-type", "application/x-www-form-urlencoded; charset=utf-8");
    client.addRequestHeader("host", service ~ ".amazonaws.com");
    client.addRequestHeader("x-amz-date", xamztime);
    client.addRequestHeader("authorization", "AWS4-HMAC-SHA256" ~ " " ~ "Credential=" ~ accKey ~ "/" ~ xamztime ~ "/" ~ zone ~ "/" ~ service ~ "/" ~ "aws4_request" ~ ", " ~ "SignedHeaders=" ~ "content-type;host;x-amz-date" ~ ", " ~ "Signature=" ~ signature);

    auto url = "ec2.amazonaws.com/?" ~ "Action=DescribeInstances&Version=2013-10-15";
    auto urlenc = encode(url);
    writeln(url);
    //auto content = get(urlenc, client);
    auto content = post("ec2.amazonaws.com", "Action=DescribeInstances&Version=2013-10-15", client);
    writeln(content);
}

But I'm still getting such response:

HTTP request returned status code 401 (Unauthorized)

In packet catched by Wireshark I can read such thing:

AWS was not able to validate provided access credentials

Where am I doing a mistake?




Aucun commentaire:

Enregistrer un commentaire