From 9fb05fba4fee76c594384f25d512315ab91f6cc9 Mon Sep 17 00:00:00 2001 From: "ben.lemasurier@gmail.com" Date: Wed, 31 Aug 2011 20:36:40 +0000 Subject: [PATCH] moved calc_signature to curl.cpp git-svn-id: http://s3fs.googlecode.com/svn/trunk@380 df820570-a93a-0410-bd06-b72b767a4274 --- src/curl.cpp | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/curl.h | 5 +++ src/s3fs.cpp | 110 -------------------------------------------------- src/s3fs.h | 4 +- 4 files changed, 118 insertions(+), 113 deletions(-) diff --git a/src/curl.cpp b/src/curl.cpp index eea464b..6394c12 100644 --- a/src/curl.cpp +++ b/src/curl.cpp @@ -29,6 +29,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -361,6 +366,113 @@ int my_curl_progress( return 0; } +/** + * Returns the Amazon AWS signature for the given parameters. + * + * @param method e.g., "GET" + * @param content_type e.g., "application/x-directory" + * @param date e.g., get_date() + * @param resource e.g., "/pub" + */ +string calc_signature( + string method, string content_type, string date, curl_slist* headers, string resource) { + int ret; + int bytes_written; + int offset; + int write_attempts = 0; + + string Signature; + string StringToSign; + StringToSign += method + "\n"; + StringToSign += "\n"; // md5 + StringToSign += content_type + "\n"; + StringToSign += date + "\n"; + int count = 0; + if(headers != 0) { + do { + if(strncmp(headers->data, "x-amz", 5) == 0) { + ++count; + StringToSign += headers->data; + StringToSign += 10; // linefeed + } + } while ((headers = headers->next) != 0); + } + + StringToSign += resource; + + const void* key = AWSSecretAccessKey.data(); + int key_len = AWSSecretAccessKey.size(); + const unsigned char* d = reinterpret_cast(StringToSign.data()); + int n = StringToSign.size(); + unsigned int md_len; + unsigned char md[EVP_MAX_MD_SIZE]; + + HMAC(evp_md, key, key_len, d, n, md, &md_len); + + BIO* b64 = BIO_new(BIO_f_base64()); + BIO* bmem = BIO_new(BIO_s_mem()); + b64 = BIO_push(b64, bmem); + + offset = 0; + for(;;) { + bytes_written = BIO_write(b64, &(md[offset]), md_len); + write_attempts++; + // -1 indicates that an error occurred, or a temporary error, such as + // the server is busy, occurred and we need to retry later. + // BIO_write can do a short write, this code addresses this condition + if(bytes_written <= 0) { + // Indicates whether a temporary error occurred or a failure to + // complete the operation occurred + if ((ret = BIO_should_retry(b64))) { + // Wait until the write can be accomplished + if(write_attempts <= 10) + continue; + + // Too many write attempts + syslog(LOG_ERR, "Failure during BIO_write, returning null String"); + BIO_free_all(b64); + Signature.clear(); + return Signature; + } else { + // If not a retry then it is an error + syslog(LOG_ERR, "Failure during BIO_write, returning null String"); + BIO_free_all(b64); + Signature.clear(); + return Signature; + } + } + + // The write request succeeded in writing some Bytes + offset += bytes_written; + md_len -= bytes_written; + + // If there is no more data to write, the request sending has been + // completed + if(md_len <= 0) + break; + } + + // Flush the data + ret = BIO_flush(b64); + if ( ret <= 0) { + syslog(LOG_ERR, "Failure during BIO_flush, returning null String"); + BIO_free_all(b64); + Signature.clear(); + return Signature; + } + + BUF_MEM *bptr; + + BIO_get_mem_ptr(b64, &bptr); + + Signature.resize(bptr->length - 1); + memcpy(&Signature[0], bptr->data, bptr->length-1); + + BIO_free_all(b64); + + return Signature; +} + void locate_bundle(void) { // See if environment variable CURL_CA_BUNDLE is set // if so, check it, if it is a good path, then set the diff --git a/src/curl.h b/src/curl.h index a704266..84891c3 100644 --- a/src/curl.h +++ b/src/curl.h @@ -21,6 +21,9 @@ extern time_t readwrite_timeout; extern bool debug; extern std::string program_name; extern std::string ssl_verify_hostname; +extern std::string AWSSecretAccessKey; + +static const EVP_MD* evp_md = EVP_sha1(); CURL *create_curl_handle(void); void destroy_curl_handle(CURL *curl_handle); @@ -29,6 +32,8 @@ size_t WriteMemoryCallback(void *ptr, size_t blockSize, size_t numBlocks, void * size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp); int my_curl_progress( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow); +std::string calc_signature( + std::string method, std::string content_type, std::string date, curl_slist* headers, std::string resource); void locate_bundle(void); #endif // S3FS_CURL_H_ diff --git a/src/s3fs.cpp b/src/s3fs.cpp index 18d09da..9ae6bda 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -283,116 +283,6 @@ void free_mvnodes(MVNODE *head) { return; } -/** - * Returns the Amazon AWS signature for the given parameters. - * - * @param method e.g., "GET" - * @param content_type e.g., "application/x-directory" - * @param date e.g., get_date() - * @param resource e.g., "/pub" - */ -string calc_signature( - string method, string content_type, string date, curl_slist* headers, string resource) { - int ret; - int bytes_written; - int offset; - int write_attempts = 0; - - string Signature; - string StringToSign; - StringToSign += method + "\n"; - StringToSign += "\n"; // md5 - StringToSign += content_type + "\n"; - StringToSign += date + "\n"; - int count = 0; - if(headers != 0) { - do { - if(strncmp(headers->data, "x-amz", 5) == 0) { - ++count; - StringToSign += headers->data; - StringToSign += 10; // linefeed - } - } while ((headers = headers->next) != 0); - } - - StringToSign += resource; - - const void* key = AWSSecretAccessKey.data(); - int key_len = AWSSecretAccessKey.size(); - const unsigned char* d = reinterpret_cast(StringToSign.data()); - int n = StringToSign.size(); - unsigned int md_len; - unsigned char md[EVP_MAX_MD_SIZE]; - - HMAC(evp_md, key, key_len, d, n, md, &md_len); - - BIO* b64 = BIO_new(BIO_f_base64()); - BIO* bmem = BIO_new(BIO_s_mem()); - b64 = BIO_push(b64, bmem); - - offset = 0; - for (;;) { - bytes_written = BIO_write(b64, &(md[offset]), md_len); - write_attempts++; - // -1 indicates that an error occurred, or a temporary error, such as - // the server is busy, occurred and we need to retry later. - // BIO_write can do a short write, this code addresses this condition - if (bytes_written <= 0) { - // Indicates whether a temporary error occurred or a failure to - // complete the operation occurred - if ((ret = BIO_should_retry(b64))) { - - // Wait until the write can be accomplished - if(write_attempts <= 10) { - continue; - } else { - // Too many write attempts - syslog(LOG_ERR, "Failure during BIO_write, returning null String"); - BIO_free_all(b64); - Signature.clear(); - return Signature; - } - } else { - // If not a retry then it is an error - syslog(LOG_ERR, "Failure during BIO_write, returning null String"); - BIO_free_all(b64); - Signature.clear(); - return Signature; - } - } - - // The write request succeeded in writing some Bytes - offset += bytes_written; - md_len -= bytes_written; - - // If there is no more data to write, the request sending has been - // completed - if (md_len <= 0) { - break; - } - } - - // Flush the data - ret = BIO_flush(b64); - if ( ret <= 0) { - syslog(LOG_ERR, "Failure during BIO_flush, returning null String"); - BIO_free_all(b64); - Signature.clear(); - return Signature; - } - - BUF_MEM *bptr; - - BIO_get_mem_ptr(b64, &bptr); - - Signature.resize(bptr->length - 1); - memcpy(&Signature[0], bptr->data, bptr->length-1); - - BIO_free_all(b64); - - return Signature; -} - static size_t header_callback(void *data, size_t blockSize, size_t numBlocks, void *userPtr) { headers_t* headers = reinterpret_cast(userPtr); string header(reinterpret_cast(data), blockSize * numBlocks); diff --git a/src/s3fs.h b/src/s3fs.h index c78920d..746e0a3 100644 --- a/src/s3fs.h +++ b/src/s3fs.h @@ -42,7 +42,7 @@ std::string mount_prefix = ""; static std::string mountpoint; std::string program_name; static std::string AWSAccessKeyId; -static std::string AWSSecretAccessKey; +std::string AWSSecretAccessKey; static mode_t root_mode = 0; static std::string passwd_file = ""; static bool utility_mode = 0; @@ -75,8 +75,6 @@ static const char hexAlphabet[] = "0123456789ABCDEF"; // http headers typedef std::map headers_t; -static const EVP_MD* evp_md = EVP_sha1(); - // fd -> flags typedef std::map s3fs_descriptors_t; static s3fs_descriptors_t s3fs_descriptors;