mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2025-02-12 23:38:27 +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 <syslog.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <curl/curl.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 <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -361,6 +366,113 @@ int my_curl_progress(
|
|||||||
return 0;
|
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) {
|
void locate_bundle(void) {
|
||||||
// See if environment variable CURL_CA_BUNDLE is set
|
// See if environment variable CURL_CA_BUNDLE is set
|
||||||
// if so, check it, if it is a good path, then set the
|
// 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 bool debug;
|
||||||
extern std::string program_name;
|
extern std::string program_name;
|
||||||
extern std::string ssl_verify_hostname;
|
extern std::string ssl_verify_hostname;
|
||||||
|
extern std::string AWSSecretAccessKey;
|
||||||
|
|
||||||
|
static const EVP_MD* evp_md = EVP_sha1();
|
||||||
|
|
||||||
CURL *create_curl_handle(void);
|
CURL *create_curl_handle(void);
|
||||||
void destroy_curl_handle(CURL *curl_handle);
|
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);
|
size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp);
|
||||||
int my_curl_progress(
|
int my_curl_progress(
|
||||||
void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
|
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);
|
void locate_bundle(void);
|
||||||
|
|
||||||
#endif // S3FS_CURL_H_
|
#endif // S3FS_CURL_H_
|
||||||
|
110
src/s3fs.cpp
110
src/s3fs.cpp
@ -283,116 +283,6 @@ void free_mvnodes(MVNODE *head) {
|
|||||||
return;
|
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) {
|
static size_t header_callback(void *data, size_t blockSize, size_t numBlocks, void *userPtr) {
|
||||||
headers_t* headers = reinterpret_cast<headers_t*>(userPtr);
|
headers_t* headers = reinterpret_cast<headers_t*>(userPtr);
|
||||||
string header(reinterpret_cast<char*>(data), blockSize * numBlocks);
|
string header(reinterpret_cast<char*>(data), blockSize * numBlocks);
|
||||||
|
@ -42,7 +42,7 @@ std::string mount_prefix = "";
|
|||||||
static std::string mountpoint;
|
static std::string mountpoint;
|
||||||
std::string program_name;
|
std::string program_name;
|
||||||
static std::string AWSAccessKeyId;
|
static std::string AWSAccessKeyId;
|
||||||
static std::string AWSSecretAccessKey;
|
std::string AWSSecretAccessKey;
|
||||||
static mode_t root_mode = 0;
|
static mode_t root_mode = 0;
|
||||||
static std::string passwd_file = "";
|
static std::string passwd_file = "";
|
||||||
static bool utility_mode = 0;
|
static bool utility_mode = 0;
|
||||||
@ -75,8 +75,6 @@ static const char hexAlphabet[] = "0123456789ABCDEF";
|
|||||||
// http headers
|
// http headers
|
||||||
typedef std::map<std::string, std::string> headers_t;
|
typedef std::map<std::string, std::string> headers_t;
|
||||||
|
|
||||||
static const EVP_MD* evp_md = EVP_sha1();
|
|
||||||
|
|
||||||
// fd -> flags
|
// fd -> flags
|
||||||
typedef std::map<int, int> s3fs_descriptors_t;
|
typedef std::map<int, int> s3fs_descriptors_t;
|
||||||
static s3fs_descriptors_t s3fs_descriptors;
|
static s3fs_descriptors_t s3fs_descriptors;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user