mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2025-02-02 10:38:25 +00:00
moved calc_signature to curl.cpp
git-svn-id: http://s3fs.googlecode.com/svn/trunk@380 df820570-a93a-0410-bd06-b72b767a4274
This commit is contained in:
parent
8d941f42b5
commit
9fb05fba4f
112
src/curl.cpp
112
src/curl.cpp
@ -29,6 +29,11 @@
|
||||
#include <syslog.h>
|
||||
#include <pthread.h>
|
||||
#include <curl/curl.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
@ -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<const unsigned char*>(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
|
||||
|
@ -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_
|
||||
|
110
src/s3fs.cpp
110
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<const unsigned char*>(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<headers_t*>(userPtr);
|
||||
string header(reinterpret_cast<char*>(data), blockSize * numBlocks);
|
||||
|
@ -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<std::string, std::string> headers_t;
|
||||
|
||||
static const EVP_MD* evp_md = EVP_sha1();
|
||||
|
||||
// fd -> flags
|
||||
typedef std::map<int, int> s3fs_descriptors_t;
|
||||
static s3fs_descriptors_t s3fs_descriptors;
|
||||
|
Loading…
x
Reference in New Issue
Block a user