Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The code below is from the OP. Originally, the post contained both the question and the answer and I am turning it into a Q&amp;A format.</p> <p>The signature has to be of the format</p> <pre><code>base64encode((HMAC-SHA1(ActionName+"AmazonS3"+XMLTimestamp))) </code></pre> <p>The HMAC, SHA1and B64 utils are available in <a href="http://www.openssl.org" rel="nofollow">openssl</a>.</p> <p>The format for SOAP requests is given by the <a href="http://doc.s3.amazonaws.com/2006-03-01/AmazonS3.wsdl" rel="nofollow">wsdl</a>.</p> <p>The REST interface is different.</p> <p>After <code>wsdl2h</code> to generate the header and soapcpp2 to generate the GSOAP client code the following will be the code to access the service:</p> <p>Requirements : <a href="http://www.openssl.org/" rel="nofollow">OpenSSL</a>, <a href="http://gsoap2.sourceforge.net/" rel="nofollow">GSOAP</a>.</p> <p>Build with the compiler preprocessor directive <code>WITH_OPENSSL</code>. Link with libraries <code>libeay32</code> and <code>ssleay32</code>.</p> <pre><code>#include "AmazonS3SoapBinding.nsmap" //generated from soapcpp2 #include "soapAmazonS3SoapBindingProxy.h" //generated from soapcpp2 #include &lt;stdio.h&gt; #include &lt;string.h&gt; #include &lt;stdarg.h&gt; #include &lt;openssl/sha.h&gt; #include &lt;openssl/hmac.h&gt; #include &lt;openssl/evp.h&gt; /* convert to base64 */ std::string base64_encodestring(char* text, int len) { EVP_ENCODE_CTX ectx; int size = len*2; size = size &gt; 64 ? size : 64; unsigned char* out = (unsigned char*)malloc( size ); int outlen = 0; int tlen = 0; EVP_EncodeInit(&amp;ectx); EVP_EncodeUpdate(&amp;ectx, out, &amp;outlen, (const unsigned char*)text, len ); tlen += outlen; EVP_EncodeFinal( &amp;ectx, out+tlen, &amp;outlen ); tlen += outlen; std::string str((char*)out, tlen ); free( out ); return str; } /* return the utc date+time in xml format */ const char* xml_datetime() { /*"YYYY-mm-ddTHH:MM:SS.000Z\"*/ const int MAX=25; static char output[MAX+1]; time_t now = time(NULL); strftime( output, MAX+1, "%Y-%m-%dT%H:%M:%S.000Z", gmtime( &amp;now ) ); std::cout &lt;&lt;output&lt;&lt;std::endl; return output; } /* first argument is the signing key */ /* all subsequent argumets are concatenated */ /* must end list with NULL */ char* aws_signature(char* key, ...) { unsigned int i, len; char *data, **list = &amp;key; static char hmac[EVP_MAX_MD_SIZE]; for (i = 1, len = 0; *(list+i) != NULL; ++i) { len += strlen( *(list+i) ); } data = (char*)malloc(sizeof(char) * (len+1)); if (data) { for ( i = 1, len = 0 ; *(list+i) != NULL ; ++i ) { strncpy( data+len, *(list+i), strlen(*(list+i)) ); len += strlen(*(list+i)); } data[len]='\0'; std::cout&lt;&lt;data&lt;&lt;std::endl; HMAC( EVP_sha1(), key, strlen(key), (unsigned char*)data, strlen(data), (unsigned char*) hmac, &amp;len ); free(data); } std::string b64data=base64_encodestring(hmac, len); strcpy(hmac,b64data.c_str()); return hmac; }; int main(void) { AmazonS3SoapBindingProxy client; soap_ssl_client_context(&amp;client, /* for encryption w/o authentication */ SOAP_SSL_NO_AUTHENTICATION, /* SOAP_SSL_DEFAULT | SOAP_SSL_SKIP_HOST_CHECK, */ /* if we don't want the host name checks since * these will change from machine to machine */ /*SOAP_SSL_DEFAULT,*/ /* use SOAP_SSL_DEFAULT in production code */ NULL, /* keyfile (cert+key): required only when client must authenticate to server (see SSL docs to create this file) */ NULL, /* password to read the keyfile */ NULL, /* optional cacert file to store trusted certificates, use cacerts.pem for all public certificates issued by common CAs */ NULL, /* optional capath to directory with trusted certificates */ NULL /* if randfile!=NULL: use a file with random data to seed randomness */ ); /* use this if you are behind a proxy server..... client.proxy_host="proxyserver"; // proxy hostname client.proxy_port=4250; client.proxy_userid="username"; // user pass if proxy client.proxy_passwd="password"; // requires authentication client.proxy_http_version="1.1"; // http version */ _ns1__ListAllMyBuckets buk_req; _ns1__ListAllMyBucketsResponse buk_resp; ns1__ListAllMyBucketsResult buk_res; buk_res.soap=&amp;client; buk_req.AWSAccessKeyId=new std::string("ACCESSKEY"); buk_req.soap=&amp;client; /* ListAllMyBuckets is the method I want to call here. * change it for other S3 services that you wish to call.*/ char *sig=aws_signature( "SECRETKEY", "AmazonS3", "ListAllMyBuckets", xml_datetime(), NULL ); buk_req.Signature=new std::string(sig); buk_req.Timestamp=new time_t(time(NULL)); buk_resp.soap=&amp;client; buk_resp.ListAllMyBucketsResponse=&amp;buk_res; client.ListAllMyBuckets(&amp;buk_req,&amp;buk_resp); client.soap_stream_fault(std::cout); std::vector&lt;ns1__ListAllMyBucketsEntry * &gt;::iterator itr; for(itr=buk_resp.ListAllMyBucketsResponse-&gt;Buckets-&gt;Bucket.begin(); itr!=buk_resp.ListAllMyBucketsResponse-&gt;Buckets-&gt;Bucket.end(); itr++ ) { std::cout&lt;&lt;(*itr)-&gt;Name&lt;&lt;std::endl; } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload