mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-11-10 06:40:59 +00:00
Merge pull request #35 from s3fs-fuse/cryptlibs
Supports more two SSL libraries for NSS and GnuTLS.
This commit is contained in:
commit
f1f7e76be5
217
configure.ac
217
configure.ac
@ -26,81 +26,186 @@ AC_CANONICAL_SYSTEM
|
|||||||
AM_INIT_AUTOMAKE()
|
AM_INIT_AUTOMAKE()
|
||||||
|
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
CXXFLAGS="$CXXFLAGS -Wall -D_FILE_OFFSET_BITS=64"
|
CXXFLAGS="$CXXFLAGS -Wall -D_FILE_OFFSET_BITS=64"
|
||||||
|
|
||||||
PKG_CHECK_MODULES([DEPS], [fuse >= 2.8.4 libcurl >= 7.0 libxml-2.0 >= 2.6 libcrypto >= 0.9])
|
dnl ----------------------------------------------
|
||||||
|
dnl Choice SSL library
|
||||||
|
dnl ----------------------------------------------
|
||||||
|
auth_lib=na
|
||||||
|
nettle_lib=no
|
||||||
|
|
||||||
dnl malloc_trim function
|
dnl
|
||||||
AC_CHECK_FUNCS(malloc_trim, , )
|
dnl nettle library
|
||||||
|
dnl
|
||||||
dnl Initializing NSS(temporally)
|
AC_MSG_CHECKING([s3fs build with nettle(GnuTLS)])
|
||||||
AC_MSG_CHECKING([Initializing libcurl build with NSS])
|
AC_ARG_WITH(
|
||||||
AC_ARG_ENABLE(
|
nettle,
|
||||||
nss-init,
|
[AS_HELP_STRING([--with-nettle], [s3fs build with nettle in GnuTLS(default no)])],
|
||||||
[
|
[
|
||||||
AS_HELP_STRING(
|
case "${withval}" in
|
||||||
[--enable-nss-init],
|
|
||||||
[Inilializing libcurl with NSS (default is no)]
|
|
||||||
)
|
|
||||||
],
|
|
||||||
[
|
|
||||||
case "${enableval}" in
|
|
||||||
yes)
|
yes)
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
nss_init_enabled=yes
|
nettle_lib=yes
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
],
|
||||||
|
[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl use openssl library for ssl
|
||||||
|
dnl
|
||||||
|
AC_MSG_CHECKING([s3fs build with OpenSSL])
|
||||||
|
AC_ARG_WITH(
|
||||||
|
openssl,
|
||||||
|
[AS_HELP_STRING([--with-openssl], [s3fs build with OpenSSL(default is no)])],
|
||||||
|
[
|
||||||
|
case "${withval}" in
|
||||||
|
yes)
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AS_IF(
|
||||||
|
[test $nettle_lib = no],
|
||||||
|
[auth_lib=openssl],
|
||||||
|
[AC_MSG_ERROR([could not set openssl with nettle, nettle is only for gnutls library])])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
],
|
||||||
|
[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl use GnuTLS library for ssl
|
||||||
|
dnl
|
||||||
|
AC_MSG_CHECKING([s3fs build with GnuTLS])
|
||||||
|
AC_ARG_WITH(
|
||||||
|
gnutls,
|
||||||
|
[AS_HELP_STRING([--with-gnutls], [s3fs build with GnuTLS(default is no)])],
|
||||||
|
[
|
||||||
|
case "${withval}" in
|
||||||
|
yes)
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AS_IF(
|
||||||
|
[test $auth_lib = na],
|
||||||
|
[
|
||||||
|
AS_IF(
|
||||||
|
[test $nettle_lib = no],
|
||||||
|
[auth_lib=gnutls],
|
||||||
|
[auth_lib=nettle])
|
||||||
|
],
|
||||||
|
[AC_MSG_ERROR([could not set gnutls because already set another ssl library])])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
],
|
||||||
|
[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl use nss library for ssl
|
||||||
|
dnl
|
||||||
|
AC_MSG_CHECKING([s3fs build with NSS])
|
||||||
|
AC_ARG_WITH(
|
||||||
|
nss,
|
||||||
|
[AS_HELP_STRING([--with-nss], [s3fs build with NSS(default is no)])],
|
||||||
|
[
|
||||||
|
case "${withval}" in
|
||||||
|
yes)
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AS_IF(
|
||||||
|
[test $auth_lib = na],
|
||||||
|
[
|
||||||
|
AS_IF(
|
||||||
|
[test $nettle_lib = no],
|
||||||
|
[auth_lib=nss],
|
||||||
|
[AC_MSG_ERROR([could not set openssl with nettle, nettle is only for gnutls library])])
|
||||||
|
],
|
||||||
|
[AC_MSG_ERROR([could not set nss because already set another ssl library])])
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
nss_init_enabled=no
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
nss_init_enabled=no
|
|
||||||
])
|
])
|
||||||
|
|
||||||
AS_IF(
|
AS_IF(
|
||||||
[test $nss_init_enabled = yes],
|
[test $auth_lib = na],
|
||||||
[
|
AS_IF(
|
||||||
AC_DEFINE(NSS_INIT_ENABLED, 1)
|
[test $nettle_lib = no],
|
||||||
AC_CHECK_LIB(nss3, NSS_NoDB_Init, , [AC_MSG_ERROR(not found NSS libraries)])
|
[auth_lib=openssl],
|
||||||
AC_CHECK_LIB(plds4, PL_ArenaFinish, , [AC_MSG_ERROR(not found PL_ArenaFinish)])
|
[AC_MSG_ERROR([could not set nettle without GnuTLS library])]
|
||||||
AC_CHECK_LIB(nspr4, PR_Cleanup, , [AC_MSG_ERROR(not found PR_Cleanup)])
|
)
|
||||||
AC_CHECK_HEADER(nss.h, , [AC_MSG_ERROR(not found nss.h)])
|
)
|
||||||
AC_CHECK_HEADER(nspr4/prinit.h, , [AC_MSG_ERROR(not found prinit.h)])
|
|
||||||
AC_PATH_PROG(NSSCONFIG, [nss-config], no)
|
|
||||||
AS_IF(
|
|
||||||
[test $NSSCONFIG = no],
|
|
||||||
[
|
|
||||||
DEPS_CFLAGS="$DEPS_CFLAGS -I/usr/include/nss3"
|
|
||||||
DEPS_LIBS="$DEPS_LIBS -lnss3"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
addcflags=`nss-config --cflags`
|
|
||||||
DEPS_CFLAGS="$DEPS_CFLAGS $addcflags"
|
|
||||||
dnl addlib=`nss-config --libs`
|
|
||||||
dnl DEPS_LIBS="$DEPS_LIBS $addlib"
|
|
||||||
DEPS_LIBS="$DEPS_LIBS -lnss3"
|
|
||||||
])
|
|
||||||
AC_PATH_PROG(NSPRCONFIG, [nspr-config], no)
|
|
||||||
AS_IF(
|
|
||||||
[test $NSPRCONFIG = no],
|
|
||||||
[
|
|
||||||
DEPS_CFLAGS="$DEPS_CFLAGS -I/usr/include/nspr4"
|
|
||||||
DEPS_LIBS="$DEPS_LIBS -lnspr4 -lplds4"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
addcflags=`nspr-config --cflags`
|
|
||||||
DEPS_CFLAGS="$DEPS_CFLAGS $addcflags"
|
|
||||||
dnl addlib=`nspr-config --libs`
|
|
||||||
dnl DEPS_LIBS="$DEPS_LIBS $addlib"
|
|
||||||
DEPS_LIBS="$DEPS_LIBS -lnspr4 -lplds4"
|
|
||||||
])
|
|
||||||
])
|
|
||||||
|
|
||||||
AS_UNSET(nss_enabled)
|
AC_MSG_CHECKING([compile s3fs with])
|
||||||
|
case "${auth_lib}" in
|
||||||
|
openssl)
|
||||||
|
AC_MSG_RESULT(OpenSSL)
|
||||||
|
PKG_CHECK_MODULES([DEPS], [fuse >= 2.8.4 libcurl >= 7.0 libxml-2.0 >= 2.6 libcrypto >= 0.9])
|
||||||
|
;;
|
||||||
|
gnutls)
|
||||||
|
AC_MSG_RESULT(GnuTLS-gcrypt)
|
||||||
|
gnutls_nettle=""
|
||||||
|
AC_CHECK_LIB(gnutls, gcry_control, [gnutls_nettle=0])
|
||||||
|
AS_IF([test "$gnutls_nettle" = ""], [AC_CHECK_LIB(gcrypt, gcry_control, [gnutls_nettle=0])])
|
||||||
|
AS_IF([test $gnutls_nettle = 0],
|
||||||
|
[
|
||||||
|
PKG_CHECK_MODULES([DEPS], [fuse >= 2.8.4 libcurl >= 7.0 libxml-2.0 >= 2.6 gnutls >= 2.12.0 ])
|
||||||
|
LIBS="-lgnutls -lgcrypt $LIBS"
|
||||||
|
AC_MSG_CHECKING([gnutls is build with])
|
||||||
|
AC_MSG_RESULT(gcrypt)
|
||||||
|
],
|
||||||
|
[AC_MSG_ERROR([GnuTLS found, but gcrypt not found])])
|
||||||
|
;;
|
||||||
|
nettle)
|
||||||
|
AC_MSG_RESULT(GnuTLS-nettle)
|
||||||
|
gnutls_nettle=""
|
||||||
|
AC_CHECK_LIB(gnutls, nettle_MD5Init, [gnutls_nettle=1])
|
||||||
|
AS_IF([test "$gnutls_nettle" = ""], [AC_CHECK_LIB(nettle, nettle_MD5Init, [gnutls_nettle=1])])
|
||||||
|
AS_IF([test $gnutls_nettle = 1],
|
||||||
|
[
|
||||||
|
PKG_CHECK_MODULES([DEPS], [fuse >= 2.8.4 libcurl >= 7.0 libxml-2.0 >= 2.6 nettle >= 2.7.1 ])
|
||||||
|
LIBS="-lgnutls -lnettle $LIBS"
|
||||||
|
AC_MSG_CHECKING([gnutls is build with])
|
||||||
|
AC_MSG_RESULT(nettle)
|
||||||
|
],
|
||||||
|
[AC_MSG_ERROR([GnuTLS found, but nettle not found])])
|
||||||
|
;;
|
||||||
|
nss)
|
||||||
|
AC_MSG_RESULT(NSS)
|
||||||
|
PKG_CHECK_MODULES([DEPS], [fuse >= 2.8.4 libcurl >= 7.0 libxml-2.0 >= 2.6 nss >= 3.15.0 ])
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_ERROR([unknown ssl library type.])
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AM_CONDITIONAL([USE_SSL_OPENSSL], [test "$auth_lib" = openssl])
|
||||||
|
AM_CONDITIONAL([USE_SSL_GNUTLS], [test "$auth_lib" = gnutls -o "$auth_lib" = nettle])
|
||||||
|
AM_CONDITIONAL([USE_GNUTLS_NETTLE], [test "$auth_lib" = nettle])
|
||||||
|
AM_CONDITIONAL([USE_SSL_NSS], [test "$auth_lib" = nss])
|
||||||
|
|
||||||
|
dnl ----------------------------------------------
|
||||||
|
dnl end of ssl library
|
||||||
|
dnl ----------------------------------------------
|
||||||
|
|
||||||
|
dnl malloc_trim function
|
||||||
|
AC_CHECK_FUNCS(malloc_trim, , )
|
||||||
|
|
||||||
AC_CONFIG_FILES(Makefile src/Makefile test/Makefile doc/Makefile)
|
AC_CONFIG_FILES(Makefile src/Makefile test/Makefile doc/Makefile)
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
@ -1,7 +1,20 @@
|
|||||||
bin_PROGRAMS=s3fs
|
bin_PROGRAMS=s3fs
|
||||||
|
|
||||||
AM_CPPFLAGS = $(DEPS_CFLAGS)
|
AM_CPPFLAGS = $(DEPS_CFLAGS)
|
||||||
|
if USE_GNUTLS_NETTLE
|
||||||
|
AM_CPPFLAGS += -DUSE_GNUTLS_NETTLE
|
||||||
|
endif
|
||||||
|
|
||||||
|
s3fs_SOURCES = s3fs.cpp s3fs.h curl.cpp curl.h cache.cpp cache.h string_util.cpp string_util.h s3fs_util.cpp s3fs_util.h fdcache.cpp fdcache.h common_auth.cpp s3fs_auth.h common.h
|
||||||
|
if USE_SSL_OPENSSL
|
||||||
|
s3fs_SOURCES += openssl_auth.cpp
|
||||||
|
endif
|
||||||
|
if USE_SSL_GNUTLS
|
||||||
|
s3fs_SOURCES += gnutls_auth.cpp
|
||||||
|
endif
|
||||||
|
if USE_SSL_NSS
|
||||||
|
s3fs_SOURCES += nss_auth.cpp
|
||||||
|
endif
|
||||||
|
|
||||||
s3fs_SOURCES = s3fs.cpp s3fs.h curl.cpp curl.h cache.cpp cache.h string_util.cpp string_util.h s3fs_util.cpp s3fs_util.h fdcache.cpp fdcache.h common.h
|
|
||||||
s3fs_LDADD = $(DEPS_LIBS)
|
s3fs_LDADD = $(DEPS_LIBS)
|
||||||
|
|
||||||
|
105
src/common_auth.cpp
Normal file
105
src/common_auth.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* s3fs - FUSE-based file system backed by Amazon S3
|
||||||
|
*
|
||||||
|
* Copyright 2007-2008 Randy Rizun <rrizun@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "s3fs_auth.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
char* s3fs_base64(unsigned char* input, size_t length)
|
||||||
|
{
|
||||||
|
static const char* base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||||
|
char* result;
|
||||||
|
|
||||||
|
if(!input || '\0' == input[0] || 0 >= length){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(NULL == (result = (char*)malloc((((length / 3) + 1) * 4 + 1) * sizeof(char)))){
|
||||||
|
return NULL; // ENOMEM
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char parts[4];
|
||||||
|
size_t rpos;
|
||||||
|
size_t wpos;
|
||||||
|
for(rpos = 0, wpos = 0; rpos < length; rpos += 3){
|
||||||
|
parts[0] = (input[rpos] & 0xfc) >> 2;
|
||||||
|
parts[1] = ((input[rpos] & 0x03) << 4) | ((((rpos + 1) < length ? input[rpos + 1] : 0x00) & 0xf0) >> 4);
|
||||||
|
parts[2] = (rpos + 1) < length ? (((input[rpos + 1] & 0x0f) << 2) | ((((rpos + 2) < length ? input[rpos + 2] : 0x00) & 0xc0) >> 6)) : 0x40;
|
||||||
|
parts[3] = (rpos + 2) < length ? (input[rpos + 2] & 0x3f) : 0x40;
|
||||||
|
|
||||||
|
result[wpos++] = base[parts[0]];
|
||||||
|
result[wpos++] = base[parts[1]];
|
||||||
|
result[wpos++] = base[parts[2]];
|
||||||
|
result[wpos++] = base[parts[3]];
|
||||||
|
}
|
||||||
|
result[wpos] = '\0';
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string s3fs_get_content_md5(int fd)
|
||||||
|
{
|
||||||
|
unsigned char* md5hex;
|
||||||
|
char* base64;
|
||||||
|
string Signature;
|
||||||
|
|
||||||
|
if(NULL == (md5hex = s3fs_md5hexsum(fd, 0, -1))){
|
||||||
|
return string("");
|
||||||
|
}
|
||||||
|
if(NULL == (base64 = s3fs_base64(md5hex, get_md5_digest_length()))){
|
||||||
|
return string(""); // ENOMEM
|
||||||
|
}
|
||||||
|
free(md5hex);
|
||||||
|
|
||||||
|
Signature = base64;
|
||||||
|
free(base64);
|
||||||
|
|
||||||
|
return Signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
string s3fs_md5sum(int fd, off_t start, ssize_t size)
|
||||||
|
{
|
||||||
|
size_t digestlen = get_md5_digest_length();
|
||||||
|
char md5[2 * digestlen + 1];
|
||||||
|
char hexbuf[3];
|
||||||
|
unsigned char* md5hex;
|
||||||
|
|
||||||
|
if(NULL == (md5hex = s3fs_md5hexsum(fd, start, size))){
|
||||||
|
return string("");
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(md5, 0, 2 * digestlen + 1);
|
||||||
|
for(size_t pos = 0; pos < digestlen; pos++){
|
||||||
|
snprintf(hexbuf, 3, "%02x", md5hex[pos]);
|
||||||
|
strncat(md5, hexbuf, 2);
|
||||||
|
}
|
||||||
|
free(md5hex);
|
||||||
|
|
||||||
|
return string(md5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// END
|
280
src/curl.cpp
280
src/curl.cpp
@ -31,11 +31,6 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <assert.h>
|
#include <assert.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 <libxml/xpath.h>
|
#include <libxml/xpath.h>
|
||||||
#include <libxml/xpathInternals.h>
|
#include <libxml/xpathInternals.h>
|
||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
@ -52,6 +47,7 @@
|
|||||||
#include "string_util.h"
|
#include "string_util.h"
|
||||||
#include "s3fs.h"
|
#include "s3fs.h"
|
||||||
#include "s3fs_util.h"
|
#include "s3fs_util.h"
|
||||||
|
#include "s3fs_auth.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -148,7 +144,6 @@ const char* BodyData::str(void) const
|
|||||||
|
|
||||||
pthread_mutex_t S3fsCurl::curl_handles_lock;
|
pthread_mutex_t S3fsCurl::curl_handles_lock;
|
||||||
pthread_mutex_t S3fsCurl::curl_share_lock[SHARE_MUTEX_MAX];
|
pthread_mutex_t S3fsCurl::curl_share_lock[SHARE_MUTEX_MAX];
|
||||||
pthread_mutex_t* S3fsCurl::crypt_mutex = NULL;
|
|
||||||
bool S3fsCurl::is_initglobal_done = false;
|
bool S3fsCurl::is_initglobal_done = false;
|
||||||
CURLSH* S3fsCurl::hCurlShare = NULL;
|
CURLSH* S3fsCurl::hCurlShare = NULL;
|
||||||
bool S3fsCurl::is_dns_cache = true; // default
|
bool S3fsCurl::is_dns_cache = true; // default
|
||||||
@ -168,7 +163,6 @@ string S3fsCurl::AWSAccessToken;
|
|||||||
time_t S3fsCurl::AWSAccessTokenExpire= 0;
|
time_t S3fsCurl::AWSAccessTokenExpire= 0;
|
||||||
string S3fsCurl::IAM_role;
|
string S3fsCurl::IAM_role;
|
||||||
long S3fsCurl::ssl_verify_hostname = 1; // default(original code...)
|
long S3fsCurl::ssl_verify_hostname = 1; // default(original code...)
|
||||||
const EVP_MD* S3fsCurl::evp_md = EVP_sha1();
|
|
||||||
curltime_t S3fsCurl::curl_times;
|
curltime_t S3fsCurl::curl_times;
|
||||||
curlprogress_t S3fsCurl::curl_progress;
|
curlprogress_t S3fsCurl::curl_progress;
|
||||||
string S3fsCurl::curl_ca_bundle;
|
string S3fsCurl::curl_ca_bundle;
|
||||||
@ -340,97 +334,12 @@ void S3fsCurl::UnlockCurlShare(CURL* handle, curl_lock_data nLockData, void* use
|
|||||||
|
|
||||||
bool S3fsCurl::InitCryptMutex(void)
|
bool S3fsCurl::InitCryptMutex(void)
|
||||||
{
|
{
|
||||||
if(S3fsCurl::crypt_mutex){
|
return s3fs_init_crypt_mutex();
|
||||||
FPRNNN("crypt_mutex is not NULL, destory it.");
|
|
||||||
if(!S3fsCurl::DestroyCryptMutex()){
|
|
||||||
DPRN("Failed to destroy crypt mutex");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(NULL == (S3fsCurl::crypt_mutex = static_cast<pthread_mutex_t*>(malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t))))){
|
|
||||||
DPRNCRIT("Could not allocate memory for crypt mutex");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for(int cnt = 0; cnt < CRYPTO_num_locks(); cnt++){
|
|
||||||
pthread_mutex_init(&S3fsCurl::crypt_mutex[cnt], NULL);
|
|
||||||
}
|
|
||||||
// static lock
|
|
||||||
CRYPTO_set_locking_callback(S3fsCurl::CryptMutexLock);
|
|
||||||
CRYPTO_set_id_callback(S3fsCurl::CryptGetThreadid);
|
|
||||||
// dynamic lock
|
|
||||||
CRYPTO_set_dynlock_create_callback(S3fsCurl::CreateDynCryptMutex);
|
|
||||||
CRYPTO_set_dynlock_lock_callback(S3fsCurl::DynCryptMutexLock);
|
|
||||||
CRYPTO_set_dynlock_destroy_callback(S3fsCurl::DestoryDynCryptMutex);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool S3fsCurl::DestroyCryptMutex(void)
|
bool S3fsCurl::DestroyCryptMutex(void)
|
||||||
{
|
{
|
||||||
if(!S3fsCurl::crypt_mutex){
|
return s3fs_destroy_crypt_mutex();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CRYPTO_set_dynlock_destroy_callback(NULL);
|
|
||||||
CRYPTO_set_dynlock_lock_callback(NULL);
|
|
||||||
CRYPTO_set_dynlock_create_callback(NULL);
|
|
||||||
CRYPTO_set_id_callback(NULL);
|
|
||||||
CRYPTO_set_locking_callback(NULL);
|
|
||||||
|
|
||||||
for(int cnt = 0; cnt < CRYPTO_num_locks(); cnt++){
|
|
||||||
pthread_mutex_destroy(&S3fsCurl::crypt_mutex[cnt]);
|
|
||||||
}
|
|
||||||
CRYPTO_cleanup_all_ex_data();
|
|
||||||
free(S3fsCurl::crypt_mutex);
|
|
||||||
S3fsCurl::crypt_mutex = NULL;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void S3fsCurl::CryptMutexLock(int mode, int pos, const char* file, int line)
|
|
||||||
{
|
|
||||||
if(S3fsCurl::crypt_mutex){
|
|
||||||
if(mode & CRYPTO_LOCK){
|
|
||||||
pthread_mutex_lock(&S3fsCurl::crypt_mutex[pos]);
|
|
||||||
}else{
|
|
||||||
pthread_mutex_unlock(&S3fsCurl::crypt_mutex[pos]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long S3fsCurl::CryptGetThreadid(void)
|
|
||||||
{
|
|
||||||
return (unsigned long)pthread_self();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CRYPTO_dynlock_value* S3fsCurl::CreateDynCryptMutex(const char* file, int line)
|
|
||||||
{
|
|
||||||
struct CRYPTO_dynlock_value* dyndata;
|
|
||||||
|
|
||||||
if(NULL == (dyndata = (struct CRYPTO_dynlock_value*)malloc(sizeof(struct CRYPTO_dynlock_value)))){
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
pthread_mutex_init(&(dyndata->dyn_mutex), NULL);
|
|
||||||
return dyndata;
|
|
||||||
}
|
|
||||||
|
|
||||||
void S3fsCurl::DynCryptMutexLock(int mode, struct CRYPTO_dynlock_value* dyndata, const char* file, int line)
|
|
||||||
{
|
|
||||||
if(dyndata){
|
|
||||||
if(mode & CRYPTO_LOCK){
|
|
||||||
pthread_mutex_lock(&(dyndata->dyn_mutex));
|
|
||||||
}else{
|
|
||||||
pthread_mutex_unlock(&(dyndata->dyn_mutex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void S3fsCurl::DestoryDynCryptMutex(struct CRYPTO_dynlock_value* dyndata, const char* file, int line)
|
|
||||||
{
|
|
||||||
if(dyndata){
|
|
||||||
pthread_mutex_destroy(&(dyndata->dyn_mutex));
|
|
||||||
free(dyndata);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// homegrown timeout mechanism
|
// homegrown timeout mechanism
|
||||||
@ -1651,10 +1560,6 @@ int S3fsCurl::RequestPerform(void)
|
|||||||
//
|
//
|
||||||
string S3fsCurl::CalcSignature(string method, string strMD5, string content_type, string date, string resource)
|
string S3fsCurl::CalcSignature(string method, string strMD5, string content_type, string date, string resource)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
int bytes_written;
|
|
||||||
int offset;
|
|
||||||
int write_attempts = 0;
|
|
||||||
string Signature;
|
string Signature;
|
||||||
string StringToSign;
|
string StringToSign;
|
||||||
|
|
||||||
@ -1682,74 +1587,20 @@ string S3fsCurl::CalcSignature(string method, string strMD5, string content_type
|
|||||||
int key_len = S3fsCurl::AWSSecretAccessKey.size();
|
int key_len = S3fsCurl::AWSSecretAccessKey.size();
|
||||||
const unsigned char* sdata = reinterpret_cast<const unsigned char*>(StringToSign.data());
|
const unsigned char* sdata = reinterpret_cast<const unsigned char*>(StringToSign.data());
|
||||||
int sdata_len = StringToSign.size();
|
int sdata_len = StringToSign.size();
|
||||||
unsigned char md[EVP_MAX_MD_SIZE];
|
unsigned char* md = NULL;
|
||||||
unsigned int md_len;
|
unsigned int md_len = 0;;
|
||||||
|
|
||||||
HMAC(S3fsCurl::evp_md, key, key_len, sdata, sdata_len, md, &md_len);
|
s3fs_HMAC(key, key_len, sdata, sdata_len, &md, &md_len);
|
||||||
|
|
||||||
BIO* b64 = BIO_new(BIO_f_base64());
|
char* base64;
|
||||||
BIO* bmem = BIO_new(BIO_s_mem());
|
if(NULL == (base64 = s3fs_base64(md, md_len))){
|
||||||
b64 = BIO_push(b64, bmem);
|
free(md);
|
||||||
|
return string(""); // ENOMEM
|
||||||
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
|
|
||||||
DPRNNN("Failure during BIO_write, returning null String");
|
|
||||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, b64, &b64->ex_data);
|
|
||||||
BIO_free_all(b64);
|
|
||||||
Signature.clear();
|
|
||||||
return Signature;
|
|
||||||
|
|
||||||
}else{
|
|
||||||
// If not a retry then it is an error
|
|
||||||
DPRNNN("Failure during BIO_write, returning null String");
|
|
||||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, b64, &b64->ex_data);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
free(md);
|
||||||
|
|
||||||
// Flush the data
|
Signature = base64;
|
||||||
ret = BIO_flush(b64);
|
free(base64);
|
||||||
if(ret <= 0){
|
|
||||||
DPRNNN("Failure during BIO_flush, returning null String");
|
|
||||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, b64, &b64->ex_data);
|
|
||||||
BIO_free_all(b64);
|
|
||||||
Signature.clear();
|
|
||||||
return Signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
BUF_MEM *bptr;
|
|
||||||
BIO_get_mem_ptr(b64, &bptr);
|
|
||||||
Signature.assign(bptr->data, bptr->length - 1);
|
|
||||||
|
|
||||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, b64, &b64->ex_data);
|
|
||||||
BIO_free_all(b64);
|
|
||||||
|
|
||||||
return Signature;
|
return Signature;
|
||||||
}
|
}
|
||||||
@ -2094,7 +1945,7 @@ int S3fsCurl::PutRequest(const char* tpath, headers_t& meta, int fd, bool ow_sse
|
|||||||
|
|
||||||
string strMD5;
|
string strMD5;
|
||||||
if(-1 != fd && S3fsCurl::is_content_md5){
|
if(-1 != fd && S3fsCurl::is_content_md5){
|
||||||
strMD5 = GetContentMD5(fd);
|
strMD5 = s3fs_get_content_md5(fd);
|
||||||
requestHeaders = curl_slist_sort_insert(requestHeaders, string("Content-MD5: " + strMD5).c_str());
|
requestHeaders = curl_slist_sort_insert(requestHeaders, string("Content-MD5: " + strMD5).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2617,7 +2468,7 @@ int S3fsCurl::UploadMultipartPostSetup(const char* tpath, int part_num, string&
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make md5 and file pointer
|
// make md5 and file pointer
|
||||||
partdata.etag = md5sum(partdata.fd, partdata.startpos, partdata.size);
|
partdata.etag = s3fs_md5sum(partdata.fd, partdata.startpos, partdata.size);
|
||||||
if(partdata.etag.empty()){
|
if(partdata.etag.empty()){
|
||||||
DPRN("Could not make md5 for file(part %d)", part_num);
|
DPRN("Could not make md5 for file(part %d)", part_num);
|
||||||
return -1;
|
return -1;
|
||||||
@ -3407,107 +3258,6 @@ bool AdditionalHeader::Dump(void) const
|
|||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
// Utility functions
|
// Utility functions
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
string GetContentMD5(int fd)
|
|
||||||
{
|
|
||||||
BIO* b64;
|
|
||||||
BIO* bmem;
|
|
||||||
BUF_MEM* bptr;
|
|
||||||
string Signature;
|
|
||||||
unsigned char* md5hex;
|
|
||||||
|
|
||||||
if(NULL == (md5hex = md5hexsum(fd, 0, -1))){
|
|
||||||
return string("");
|
|
||||||
}
|
|
||||||
|
|
||||||
b64 = BIO_new(BIO_f_base64());
|
|
||||||
bmem = BIO_new(BIO_s_mem());
|
|
||||||
b64 = BIO_push(b64, bmem);
|
|
||||||
|
|
||||||
BIO_write(b64, md5hex, MD5_DIGEST_LENGTH);
|
|
||||||
free(md5hex);
|
|
||||||
if(1 != BIO_flush(b64)){
|
|
||||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, b64, &b64->ex_data);
|
|
||||||
BIO_free_all(b64);
|
|
||||||
return string("");
|
|
||||||
}
|
|
||||||
BIO_get_mem_ptr(b64, &bptr);
|
|
||||||
Signature.assign(bptr->data, bptr->length - 1);
|
|
||||||
|
|
||||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, b64, &b64->ex_data);
|
|
||||||
BIO_free_all(b64);
|
|
||||||
|
|
||||||
return Signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char* md5hexsum(int fd, off_t start, ssize_t size)
|
|
||||||
{
|
|
||||||
MD5_CTX c;
|
|
||||||
char buf[512];
|
|
||||||
ssize_t bytes;
|
|
||||||
unsigned char* result;
|
|
||||||
|
|
||||||
if(-1 == size){
|
|
||||||
struct stat st;
|
|
||||||
if(-1 == fstat(fd, &st)){
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
size = static_cast<ssize_t>(st.st_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// seek to top of file.
|
|
||||||
if(-1 == lseek(fd, start, SEEK_SET)){
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if(NULL == (result = (unsigned char*)malloc(MD5_DIGEST_LENGTH))){
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buf, 0, 512);
|
|
||||||
MD5_Init(&c);
|
|
||||||
for(ssize_t total = 0; total < size; total += bytes){
|
|
||||||
bytes = 512 < (size - total) ? 512 : (size - total);
|
|
||||||
bytes = read(fd, buf, bytes);
|
|
||||||
if(0 == bytes){
|
|
||||||
// end of file
|
|
||||||
break;
|
|
||||||
}else if(-1 == bytes){
|
|
||||||
// error
|
|
||||||
DPRNNN("file read error(%d)", errno);
|
|
||||||
free(result);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
MD5_Update(&c, buf, bytes);
|
|
||||||
memset(buf, 0, 512);
|
|
||||||
}
|
|
||||||
MD5_Final(result, &c);
|
|
||||||
|
|
||||||
if(-1 == lseek(fd, start, SEEK_SET)){
|
|
||||||
free(result);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
string md5sum(int fd, off_t start, ssize_t size)
|
|
||||||
{
|
|
||||||
char md5[2 * MD5_DIGEST_LENGTH + 1];
|
|
||||||
char hexbuf[3];
|
|
||||||
unsigned char* md5hex;
|
|
||||||
|
|
||||||
if(NULL == (md5hex = md5hexsum(fd, start, size))){
|
|
||||||
return string("");
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(md5, 0, 2 * MD5_DIGEST_LENGTH + 1);
|
|
||||||
for(int i = 0; i < MD5_DIGEST_LENGTH; i++) {
|
|
||||||
snprintf(hexbuf, 3, "%02x", md5hex[i]);
|
|
||||||
strncat(md5, hexbuf, 2);
|
|
||||||
}
|
|
||||||
free(md5hex);
|
|
||||||
|
|
||||||
return string(md5);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// curl_slist_sort_insert
|
// curl_slist_sort_insert
|
||||||
// This function is like curl_slist_append function, but this adds data by a-sorting.
|
// This function is like curl_slist_append function, but this adds data by a-sorting.
|
||||||
|
13
src/curl.h
13
src/curl.h
@ -106,12 +106,6 @@ typedef std::map<std::string, std::string> iamcredmap_t;
|
|||||||
#define SHARE_MUTEX_SSL_SESSION 1
|
#define SHARE_MUTEX_SSL_SESSION 1
|
||||||
#define SHARE_MUTEX_MAX 2
|
#define SHARE_MUTEX_MAX 2
|
||||||
|
|
||||||
// internal use struct for openssl
|
|
||||||
struct CRYPTO_dynlock_value
|
|
||||||
{
|
|
||||||
pthread_mutex_t dyn_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Class for lapping curl
|
// Class for lapping curl
|
||||||
//
|
//
|
||||||
class S3fsCurl
|
class S3fsCurl
|
||||||
@ -140,7 +134,6 @@ class S3fsCurl
|
|||||||
// class variables
|
// class variables
|
||||||
static pthread_mutex_t curl_handles_lock;
|
static pthread_mutex_t curl_handles_lock;
|
||||||
static pthread_mutex_t curl_share_lock[SHARE_MUTEX_MAX];
|
static pthread_mutex_t curl_share_lock[SHARE_MUTEX_MAX];
|
||||||
static pthread_mutex_t* crypt_mutex;
|
|
||||||
static bool is_initglobal_done;
|
static bool is_initglobal_done;
|
||||||
static CURLSH* hCurlShare;
|
static CURLSH* hCurlShare;
|
||||||
static bool is_dns_cache;
|
static bool is_dns_cache;
|
||||||
@ -160,7 +153,6 @@ class S3fsCurl
|
|||||||
static time_t AWSAccessTokenExpire;
|
static time_t AWSAccessTokenExpire;
|
||||||
static std::string IAM_role;
|
static std::string IAM_role;
|
||||||
static long ssl_verify_hostname;
|
static long ssl_verify_hostname;
|
||||||
static const EVP_MD* evp_md;
|
|
||||||
static curltime_t curl_times;
|
static curltime_t curl_times;
|
||||||
static curlprogress_t curl_progress;
|
static curlprogress_t curl_progress;
|
||||||
static std::string curl_ca_bundle;
|
static std::string curl_ca_bundle;
|
||||||
@ -206,11 +198,6 @@ class S3fsCurl
|
|||||||
static void UnlockCurlShare(CURL* handle, curl_lock_data nLockData, void* useptr);
|
static void UnlockCurlShare(CURL* handle, curl_lock_data nLockData, void* useptr);
|
||||||
static bool InitCryptMutex(void);
|
static bool InitCryptMutex(void);
|
||||||
static bool DestroyCryptMutex(void);
|
static bool DestroyCryptMutex(void);
|
||||||
static void CryptMutexLock(int mode, int pos, const char* file, int line);
|
|
||||||
static unsigned long CryptGetThreadid(void);
|
|
||||||
static struct CRYPTO_dynlock_value* CreateDynCryptMutex(const char* file, int line);
|
|
||||||
static void DynCryptMutexLock(int mode, struct CRYPTO_dynlock_value* dyndata, const char* file, int line);
|
|
||||||
static void DestoryDynCryptMutex(struct CRYPTO_dynlock_value* dyndata, const char* file, int line);
|
|
||||||
static int CurlProgress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
|
static int CurlProgress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
|
||||||
|
|
||||||
static bool InitMimeType(const char* MimeFile = NULL);
|
static bool InitMimeType(const char* MimeFile = NULL);
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include <openssl/crypto.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -797,7 +796,7 @@ int FdEntity::Load(off_t start, off_t size)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// download
|
// download
|
||||||
if((*iter)->bytes >= (2 * S3fsCurl::GetMultipartSize()) && !nomultipart){ // default 20MB
|
if((*iter)->bytes >= static_cast<size_t>(2 * S3fsCurl::GetMultipartSize()) && !nomultipart){ // default 20MB
|
||||||
// parallel request
|
// parallel request
|
||||||
// Additional time is needed for large files
|
// Additional time is needed for large files
|
||||||
time_t backup = 0;
|
time_t backup = 0;
|
||||||
@ -1197,3 +1196,4 @@ bool FdManager::Close(FdEntity* ent)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// END
|
||||||
|
259
src/gnutls_auth.cpp
Normal file
259
src/gnutls_auth.cpp
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
* s3fs - FUSE-based file system backed by Amazon S3
|
||||||
|
*
|
||||||
|
* Copyright 2007-2008 Randy Rizun <rrizun@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <gcrypt.h>
|
||||||
|
#include <gnutls/gnutls.h>
|
||||||
|
#include <gnutls/crypto.h>
|
||||||
|
#ifdef USE_GNUTLS_NETTLE
|
||||||
|
#include <nettle/md5.h>
|
||||||
|
#include <nettle/sha1.h>
|
||||||
|
#include <nettle/hmac.h>
|
||||||
|
#endif
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "s3fs_auth.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for version
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
#ifdef USE_GNUTLS_NETTLE
|
||||||
|
|
||||||
|
const char* s3fs_crypt_lib_name(void)
|
||||||
|
{
|
||||||
|
static const char version[] = "GnuTLS(nettle)";
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // USE_GNUTLS_NETTLE
|
||||||
|
|
||||||
|
const char* s3fs_crypt_lib_name(void)
|
||||||
|
{
|
||||||
|
static const char version[] = "GnuTLS(gcrypt)";
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_GNUTLS_NETTLE
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for global init
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
bool s3fs_init_global_ssl(void)
|
||||||
|
{
|
||||||
|
if(GNUTLS_E_SUCCESS != gnutls_global_init()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool s3fs_destroy_global_ssl(void)
|
||||||
|
{
|
||||||
|
gnutls_global_deinit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for crypt lock
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
bool s3fs_init_crypt_mutex(void)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool s3fs_destroy_crypt_mutex(void)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for HMAC
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
#ifdef USE_GNUTLS_NETTLE
|
||||||
|
|
||||||
|
bool s3fs_HMAC(const void* key, size_t keylen, const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen)
|
||||||
|
{
|
||||||
|
if(!key || 0 >= keylen || !data || 0 >= datalen || !digest || !digestlen){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(NULL == (*digest = (unsigned char*)malloc(SHA1_DIGEST_SIZE))){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hmac_sha1_ctx ctx_hmac;
|
||||||
|
hmac_sha1_set_key(&ctx_hmac, keylen, reinterpret_cast<const uint8_t*>(key));
|
||||||
|
hmac_sha1_update(&ctx_hmac, datalen, reinterpret_cast<const uint8_t*>(data));
|
||||||
|
hmac_sha1_digest(&ctx_hmac, SHA1_DIGEST_SIZE, reinterpret_cast<uint8_t*>(*digest));
|
||||||
|
*digestlen = SHA1_DIGEST_SIZE;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // USE_GNUTLS_NETTLE
|
||||||
|
|
||||||
|
bool s3fs_HMAC(const void* key, size_t keylen, const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen)
|
||||||
|
{
|
||||||
|
if(!key || 0 >= keylen || !data || 0 >= datalen || !digest || !digestlen){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(0 >= (*digestlen = gnutls_hmac_get_len(GNUTLS_MAC_SHA1))){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(NULL == (*digest = (unsigned char*)malloc(*digestlen + 1))){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(0 > gnutls_hmac_fast(GNUTLS_MAC_SHA1, key, keylen, data, datalen, *digest)){
|
||||||
|
free(*digest);
|
||||||
|
*digest = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_GNUTLS_NETTLE
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for MD5
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
#define MD5_DIGEST_LENGTH 16
|
||||||
|
|
||||||
|
size_t get_md5_digest_length(void)
|
||||||
|
{
|
||||||
|
return MD5_DIGEST_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_GNUTLS_NETTLE
|
||||||
|
unsigned char* s3fs_md5hexsum(int fd, off_t start, ssize_t size)
|
||||||
|
{
|
||||||
|
struct md5_ctx ctx_md5;
|
||||||
|
unsigned char buf[512];
|
||||||
|
ssize_t bytes;
|
||||||
|
unsigned char* result;
|
||||||
|
|
||||||
|
// seek to top of file.
|
||||||
|
if(-1 == lseek(fd, start, SEEK_SET)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
md5_init(&ctx_md5);
|
||||||
|
|
||||||
|
for(ssize_t total = 0; total < size; total += bytes){
|
||||||
|
bytes = 512 < (size - total) ? 512 : (size - total);
|
||||||
|
bytes = read(fd, buf, bytes);
|
||||||
|
if(0 == bytes){
|
||||||
|
// end of file
|
||||||
|
break;
|
||||||
|
}else if(-1 == bytes){
|
||||||
|
// error
|
||||||
|
DPRNNN("file read error(%d)", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
md5_update(&ctx_md5, bytes, buf);
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
}
|
||||||
|
if(NULL == (result = (unsigned char*)malloc(get_md5_digest_length()))){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
md5_digest(&ctx_md5, get_md5_digest_length(), result);
|
||||||
|
|
||||||
|
if(-1 == lseek(fd, start, SEEK_SET)){
|
||||||
|
free(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // USE_GNUTLS_NETTLE
|
||||||
|
|
||||||
|
unsigned char* s3fs_md5hexsum(int fd, off_t start, ssize_t size)
|
||||||
|
{
|
||||||
|
gcry_md_hd_t ctx_md5;
|
||||||
|
gcry_error_t err;
|
||||||
|
char buf[512];
|
||||||
|
ssize_t bytes;
|
||||||
|
unsigned char* result;
|
||||||
|
|
||||||
|
if(-1 == size){
|
||||||
|
struct stat st;
|
||||||
|
if(-1 == fstat(fd, &st)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size = static_cast<ssize_t>(st.st_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// seek to top of file.
|
||||||
|
if(-1 == lseek(fd, start, SEEK_SET)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
if(GPG_ERR_NO_ERROR != (err = gcry_md_open(&ctx_md5, GCRY_MD_MD5, 0))){
|
||||||
|
DPRNN("MD5 context creation failure: %s/%s", gcry_strsource(err), gcry_strerror(err));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(ssize_t total = 0; total < size; total += bytes){
|
||||||
|
bytes = 512 < (size - total) ? 512 : (size - total);
|
||||||
|
bytes = read(fd, buf, bytes);
|
||||||
|
if(0 == bytes){
|
||||||
|
// end of file
|
||||||
|
break;
|
||||||
|
}else if(-1 == bytes){
|
||||||
|
// error
|
||||||
|
DPRNNN("file read error(%d)", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
gcry_md_write(ctx_md5, buf, bytes);
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
}
|
||||||
|
if(NULL == (result = (unsigned char*)malloc(get_md5_digest_length()))){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy(result, gcry_md_read(ctx_md5, 0), get_md5_digest_length());
|
||||||
|
gcry_md_close(ctx_md5);
|
||||||
|
|
||||||
|
if(-1 == lseek(fd, start, SEEK_SET)){
|
||||||
|
free(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_GNUTLS_NETTLE
|
||||||
|
|
||||||
|
/// END
|
196
src/nss_auth.cpp
Normal file
196
src/nss_auth.cpp
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* s3fs - FUSE-based file system backed by Amazon S3
|
||||||
|
*
|
||||||
|
* Copyright 2007-2008 Randy Rizun <rrizun@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <nss.h>
|
||||||
|
#include <pk11pub.h>
|
||||||
|
#include <hasht.h>
|
||||||
|
#include <prinit.h>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "s3fs_auth.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for version
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
const char* s3fs_crypt_lib_name(void)
|
||||||
|
{
|
||||||
|
static const char version[] = "NSS";
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for global init
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
bool s3fs_init_global_ssl(void)
|
||||||
|
{
|
||||||
|
NSS_Init(NULL);
|
||||||
|
NSS_NoDB_Init(NULL);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool s3fs_destroy_global_ssl(void)
|
||||||
|
{
|
||||||
|
NSS_Shutdown();
|
||||||
|
PL_ArenaFinish();
|
||||||
|
PR_Cleanup();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for crypt lock
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
bool s3fs_init_crypt_mutex(void)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool s3fs_destroy_crypt_mutex(void)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for HMAC
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
bool s3fs_HMAC(const void* key, size_t keylen, const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen)
|
||||||
|
{
|
||||||
|
if(!key || 0 >= keylen || !data || 0 >= datalen || !digest || !digestlen){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PK11SlotInfo* Slot;
|
||||||
|
PK11SymKey* pKey;
|
||||||
|
PK11Context* Context;
|
||||||
|
SECStatus SecStatus;
|
||||||
|
unsigned char tmpdigest[64];
|
||||||
|
SECItem KeySecItem = {siBuffer, reinterpret_cast<unsigned char*>(const_cast<void*>(key)), keylen};
|
||||||
|
SECItem NullSecItem = {siBuffer, NULL, 0};
|
||||||
|
|
||||||
|
if(NULL == (Slot = PK11_GetInternalKeySlot())){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(NULL == (pKey = PK11_ImportSymKey(Slot, CKM_SHA_1_HMAC, PK11_OriginUnwrap, CKA_SIGN, &KeySecItem, NULL))){
|
||||||
|
PK11_FreeSlot(Slot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(NULL == (Context = PK11_CreateContextBySymKey(CKM_SHA_1_HMAC, CKA_SIGN, pKey, &NullSecItem))){
|
||||||
|
PK11_FreeSymKey(pKey);
|
||||||
|
PK11_FreeSlot(Slot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*digestlen = 0;
|
||||||
|
if(SECSuccess != (SecStatus = PK11_DigestBegin(Context)) ||
|
||||||
|
SECSuccess != (SecStatus = PK11_DigestOp(Context, data, datalen)) ||
|
||||||
|
SECSuccess != (SecStatus = PK11_DigestFinal(Context, tmpdigest, digestlen, sizeof(tmpdigest))) )
|
||||||
|
{
|
||||||
|
PK11_DestroyContext(Context, PR_TRUE);
|
||||||
|
PK11_FreeSymKey(pKey);
|
||||||
|
PK11_FreeSlot(Slot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PK11_DestroyContext(Context, PR_TRUE);
|
||||||
|
PK11_FreeSymKey(pKey);
|
||||||
|
PK11_FreeSlot(Slot);
|
||||||
|
|
||||||
|
if(NULL == (*digest = (unsigned char*)malloc(*digestlen))){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(*digest, tmpdigest, *digestlen);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for MD5
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
size_t get_md5_digest_length(void)
|
||||||
|
{
|
||||||
|
return MD5_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* s3fs_md5hexsum(int fd, off_t start, ssize_t size)
|
||||||
|
{
|
||||||
|
PK11Context* md5ctx;
|
||||||
|
unsigned char buf[512];
|
||||||
|
ssize_t bytes;
|
||||||
|
unsigned char* result;
|
||||||
|
unsigned int md5outlen;
|
||||||
|
|
||||||
|
if(-1 == size){
|
||||||
|
struct stat st;
|
||||||
|
if(-1 == fstat(fd, &st)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size = static_cast<ssize_t>(st.st_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// seek to top of file.
|
||||||
|
if(-1 == lseek(fd, start, SEEK_SET)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
md5ctx = PK11_CreateDigestContext(SEC_OID_MD5);
|
||||||
|
|
||||||
|
for(ssize_t total = 0; total < size; total += bytes){
|
||||||
|
bytes = 512 < (size - total) ? 512 : (size - total);
|
||||||
|
bytes = read(fd, buf, bytes);
|
||||||
|
if(0 == bytes){
|
||||||
|
// end of file
|
||||||
|
break;
|
||||||
|
}else if(-1 == bytes){
|
||||||
|
// error
|
||||||
|
DPRNNN("file read error(%d)", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PK11_DigestOp(md5ctx, buf, bytes);
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
}
|
||||||
|
if(NULL == (result = (unsigned char*)malloc(get_md5_digest_length()))){
|
||||||
|
PK11_DestroyContext(md5ctx, PR_TRUE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PK11_DigestFinal(md5ctx, result, &md5outlen, get_md5_digest_length());
|
||||||
|
PK11_DestroyContext(md5ctx, PR_TRUE);
|
||||||
|
|
||||||
|
if(-1 == lseek(fd, start, SEEK_SET)){
|
||||||
|
free(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// END
|
256
src/openssl_auth.cpp
Normal file
256
src/openssl_auth.cpp
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
/*
|
||||||
|
* s3fs - FUSE-based file system backed by Amazon S3
|
||||||
|
*
|
||||||
|
* Copyright 2007-2008 Randy Rizun <rrizun@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/buffer.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "s3fs_auth.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for version
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
const char* s3fs_crypt_lib_name(void)
|
||||||
|
{
|
||||||
|
static const char version[] = "OpenSSL";
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for global init
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
bool s3fs_init_global_ssl(void)
|
||||||
|
{
|
||||||
|
ERR_load_crypto_strings();
|
||||||
|
ERR_load_BIO_strings();
|
||||||
|
OpenSSL_add_all_algorithms();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool s3fs_destroy_global_ssl(void)
|
||||||
|
{
|
||||||
|
EVP_cleanup();
|
||||||
|
ERR_free_strings();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for crypt lock
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// internal use struct for openssl
|
||||||
|
struct CRYPTO_dynlock_value
|
||||||
|
{
|
||||||
|
pthread_mutex_t dyn_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
static pthread_mutex_t* s3fs_crypt_mutex = NULL;
|
||||||
|
|
||||||
|
static void s3fs_crypt_mutex_lock(int mode, int pos, const char* file, int line)
|
||||||
|
{
|
||||||
|
if(s3fs_crypt_mutex){
|
||||||
|
if(mode & CRYPTO_LOCK){
|
||||||
|
pthread_mutex_lock(&s3fs_crypt_mutex[pos]);
|
||||||
|
}else{
|
||||||
|
pthread_mutex_unlock(&s3fs_crypt_mutex[pos]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long s3fs_crypt_get_threadid(void)
|
||||||
|
{
|
||||||
|
return static_cast<unsigned long>(pthread_self());
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct CRYPTO_dynlock_value* s3fs_dyn_crypt_mutex(const char* file, int line)
|
||||||
|
{
|
||||||
|
struct CRYPTO_dynlock_value* dyndata;
|
||||||
|
|
||||||
|
if(NULL == (dyndata = static_cast<struct CRYPTO_dynlock_value*>(malloc(sizeof(struct CRYPTO_dynlock_value))))){
|
||||||
|
DPRNCRIT("Could not allocate memory for CRYPTO_dynlock_value");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pthread_mutex_init(&(dyndata->dyn_mutex), NULL);
|
||||||
|
return dyndata;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s3fs_dyn_crypt_mutex_lock(int mode, struct CRYPTO_dynlock_value* dyndata, const char* file, int line)
|
||||||
|
{
|
||||||
|
if(dyndata){
|
||||||
|
if(mode & CRYPTO_LOCK){
|
||||||
|
pthread_mutex_lock(&(dyndata->dyn_mutex));
|
||||||
|
}else{
|
||||||
|
pthread_mutex_unlock(&(dyndata->dyn_mutex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s3fs_destroy_dyn_crypt_mutex(struct CRYPTO_dynlock_value* dyndata, const char* file, int line)
|
||||||
|
{
|
||||||
|
if(dyndata){
|
||||||
|
pthread_mutex_destroy(&(dyndata->dyn_mutex));
|
||||||
|
free(dyndata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool s3fs_init_crypt_mutex(void)
|
||||||
|
{
|
||||||
|
if(s3fs_crypt_mutex){
|
||||||
|
FPRNNN("s3fs_crypt_mutex is not NULL, destory it.");
|
||||||
|
if(!s3fs_destroy_crypt_mutex()){
|
||||||
|
DPRN("Failed to s3fs_crypt_mutex");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(NULL == (s3fs_crypt_mutex = static_cast<pthread_mutex_t*>(malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t))))){
|
||||||
|
DPRNCRIT("Could not allocate memory for s3fs_crypt_mutex");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(int cnt = 0; cnt < CRYPTO_num_locks(); cnt++){
|
||||||
|
pthread_mutex_init(&s3fs_crypt_mutex[cnt], NULL);
|
||||||
|
}
|
||||||
|
// static lock
|
||||||
|
CRYPTO_set_locking_callback(s3fs_crypt_mutex_lock);
|
||||||
|
CRYPTO_set_id_callback(s3fs_crypt_get_threadid);
|
||||||
|
// dynamic lock
|
||||||
|
CRYPTO_set_dynlock_create_callback(s3fs_dyn_crypt_mutex);
|
||||||
|
CRYPTO_set_dynlock_lock_callback(s3fs_dyn_crypt_mutex_lock);
|
||||||
|
CRYPTO_set_dynlock_destroy_callback(s3fs_destroy_dyn_crypt_mutex);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool s3fs_destroy_crypt_mutex(void)
|
||||||
|
{
|
||||||
|
if(!s3fs_crypt_mutex){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CRYPTO_set_dynlock_destroy_callback(NULL);
|
||||||
|
CRYPTO_set_dynlock_lock_callback(NULL);
|
||||||
|
CRYPTO_set_dynlock_create_callback(NULL);
|
||||||
|
CRYPTO_set_id_callback(NULL);
|
||||||
|
CRYPTO_set_locking_callback(NULL);
|
||||||
|
|
||||||
|
for(int cnt = 0; cnt < CRYPTO_num_locks(); cnt++){
|
||||||
|
pthread_mutex_destroy(&s3fs_crypt_mutex[cnt]);
|
||||||
|
}
|
||||||
|
CRYPTO_cleanup_all_ex_data();
|
||||||
|
free(s3fs_crypt_mutex);
|
||||||
|
s3fs_crypt_mutex = NULL;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for HMAC
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
bool s3fs_HMAC(const void* key, size_t keylen, const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen)
|
||||||
|
{
|
||||||
|
if(!key || 0 >= keylen || !data || 0 >= datalen || !digest || !digestlen){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
(*digestlen) = EVP_MAX_MD_SIZE * sizeof(unsigned char);
|
||||||
|
if(NULL == ((*digest) = (unsigned char*)malloc(*digestlen))){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
HMAC(EVP_sha1(), key, keylen, data, datalen, *digest, digestlen);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility Function for MD5
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
size_t get_md5_digest_length(void)
|
||||||
|
{
|
||||||
|
return MD5_DIGEST_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* s3fs_md5hexsum(int fd, off_t start, ssize_t size)
|
||||||
|
{
|
||||||
|
MD5_CTX md5ctx;
|
||||||
|
char buf[512];
|
||||||
|
ssize_t bytes;
|
||||||
|
unsigned char* result;
|
||||||
|
|
||||||
|
if(-1 == size){
|
||||||
|
struct stat st;
|
||||||
|
if(-1 == fstat(fd, &st)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size = static_cast<ssize_t>(st.st_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// seek to top of file.
|
||||||
|
if(-1 == lseek(fd, start, SEEK_SET)){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
MD5_Init(&md5ctx);
|
||||||
|
|
||||||
|
for(ssize_t total = 0; total < size; total += bytes){
|
||||||
|
bytes = 512 < (size - total) ? 512 : (size - total);
|
||||||
|
bytes = read(fd, buf, bytes);
|
||||||
|
if(0 == bytes){
|
||||||
|
// end of file
|
||||||
|
break;
|
||||||
|
}else if(-1 == bytes){
|
||||||
|
// error
|
||||||
|
DPRNNN("file read error(%d)", errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
MD5_Update(&md5ctx, buf, bytes);
|
||||||
|
memset(buf, 0, 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(NULL == (result = (unsigned char*)malloc(get_md5_digest_length()))){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
MD5_Final(result, &md5ctx);
|
||||||
|
|
||||||
|
if(-1 == lseek(fd, start, SEEK_SET)){
|
||||||
|
free(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// END
|
34
src/s3fs.cpp
34
src/s3fs.cpp
@ -31,7 +31,6 @@
|
|||||||
#include <libxml/xpathInternals.h>
|
#include <libxml/xpathInternals.h>
|
||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include <openssl/crypto.h>
|
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -50,6 +49,7 @@
|
|||||||
#include "string_util.h"
|
#include "string_util.h"
|
||||||
#include "s3fs_util.h"
|
#include "s3fs_util.h"
|
||||||
#include "fdcache.h"
|
#include "fdcache.h"
|
||||||
|
#include "s3fs_auth.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -2595,7 +2595,13 @@ static int remote_mountpath_exists(const char* path)
|
|||||||
static void* s3fs_init(struct fuse_conn_info* conn)
|
static void* s3fs_init(struct fuse_conn_info* conn)
|
||||||
{
|
{
|
||||||
FPRN("init");
|
FPRN("init");
|
||||||
LOWSYSLOGPRINT(LOG_ERR, "init $Rev$");
|
LOWSYSLOGPRINT(LOG_ERR, "init v%s (%s)", VERSION, s3fs_crypt_lib_name());
|
||||||
|
|
||||||
|
// ssl init
|
||||||
|
if(!s3fs_init_global_ssl()){
|
||||||
|
fprintf(stderr, "%s: could not initialize for ssl libraries.\n", program_name.c_str());
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// init curl
|
// init curl
|
||||||
if(!S3fsCurl::InitS3fsCurl("/etc/mime.types")){
|
if(!S3fsCurl::InitS3fsCurl("/etc/mime.types")){
|
||||||
@ -2637,6 +2643,8 @@ static void s3fs_destroy(void*)
|
|||||||
if(is_remove_cache && !FdManager::DeleteCacheDirectory()){
|
if(is_remove_cache && !FdManager::DeleteCacheDirectory()){
|
||||||
DPRN("Could not remove cache directory.");
|
DPRN("Could not remove cache directory.");
|
||||||
}
|
}
|
||||||
|
// ssl
|
||||||
|
s3fs_destroy_global_ssl();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s3fs_access(const char* path, int mask)
|
static int s3fs_access(const char* path, int mask)
|
||||||
@ -2840,10 +2848,17 @@ static int s3fs_utility_mode(void)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ssl init
|
||||||
|
if(!s3fs_init_global_ssl()){
|
||||||
|
fprintf(stderr, "%s: could not initialize for ssl libraries.\n", program_name.c_str());
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
// init curl
|
// init curl
|
||||||
if(!S3fsCurl::InitS3fsCurl("/etc/mime.types")){
|
if(!S3fsCurl::InitS3fsCurl("/etc/mime.types")){
|
||||||
fprintf(stderr, "%s: Could not initiate curl library.\n", program_name.c_str());
|
fprintf(stderr, "%s: Could not initiate curl library.\n", program_name.c_str());
|
||||||
LOWSYSLOGPRINT(LOG_ERR, "Could not initiate curl library.");
|
LOWSYSLOGPRINT(LOG_ERR, "Could not initiate curl library.");
|
||||||
|
s3fs_destroy_global_ssl();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2888,6 +2903,10 @@ static int s3fs_utility_mode(void)
|
|||||||
if(!S3fsCurl::DestroyS3fsCurl()){
|
if(!S3fsCurl::DestroyS3fsCurl()){
|
||||||
DPRN("Could not release curl library.");
|
DPRN("Could not release curl library.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ssl
|
||||||
|
s3fs_destroy_global_ssl();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3872,15 +3891,17 @@ int main(int argc, char* argv[])
|
|||||||
s3fs_oper.access = s3fs_access;
|
s3fs_oper.access = s3fs_access;
|
||||||
s3fs_oper.create = s3fs_create;
|
s3fs_oper.create = s3fs_create;
|
||||||
|
|
||||||
// init NSS
|
if(!s3fs_init_global_ssl()){
|
||||||
S3FS_INIT_NSS();
|
fprintf(stderr, "%s: could not initialize for ssl libraries.\n", program_name.c_str());
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// now passing things off to fuse, fuse will finish evaluating the command line args
|
// now passing things off to fuse, fuse will finish evaluating the command line args
|
||||||
fuse_res = fuse_main(custom_args.argc, custom_args.argv, &s3fs_oper, NULL);
|
fuse_res = fuse_main(custom_args.argc, custom_args.argv, &s3fs_oper, NULL);
|
||||||
fuse_opt_free_args(&custom_args);
|
fuse_opt_free_args(&custom_args);
|
||||||
|
|
||||||
// cleanup NSS
|
s3fs_destroy_global_ssl();
|
||||||
S3FS_CLEANUP_NSS();
|
|
||||||
// cleanup xml2
|
// cleanup xml2
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
S3FS_MALLOCTRIM(0);
|
S3FS_MALLOCTRIM(0);
|
||||||
@ -3888,3 +3909,4 @@ int main(int argc, char* argv[])
|
|||||||
exit(fuse_res);
|
exit(fuse_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// END
|
||||||
|
32
src/s3fs.h
32
src/s3fs.h
@ -65,36 +65,4 @@
|
|||||||
|
|
||||||
#endif // HAVE_MALLOC_TRIM
|
#endif // HAVE_MALLOC_TRIM
|
||||||
|
|
||||||
//
|
|
||||||
// For initializing libcurl with NSS
|
|
||||||
// Normally libcurl initializes the NSS library, but usually allows
|
|
||||||
// you to initialize s3fs forcibly. Because Memory leak is reported
|
|
||||||
// in valgrind(about curl_global_init() function), and this is for
|
|
||||||
// the cancellation. When "--enable-nss-init" option is specified
|
|
||||||
// at configurarion, it makes NSS_INIT_ENABLED flag into Makefile.
|
|
||||||
// NOTICE
|
|
||||||
// This defines and macros is temporary, and this should be deleted.
|
|
||||||
//
|
|
||||||
#ifdef NSS_INIT_ENABLED
|
|
||||||
#include <nss.h>
|
|
||||||
#include <prinit.h>
|
|
||||||
|
|
||||||
#define S3FS_INIT_NSS() \
|
|
||||||
{ \
|
|
||||||
NSS_NoDB_Init(NULL); \
|
|
||||||
}
|
|
||||||
#define S3FS_CLEANUP_NSS() \
|
|
||||||
{ \
|
|
||||||
NSS_Shutdown(); \
|
|
||||||
PL_ArenaFinish(); \
|
|
||||||
PR_Cleanup(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // NSS_INIT_ENABLED
|
|
||||||
|
|
||||||
#define S3FS_INIT_NSS()
|
|
||||||
#define S3FS_CLEANUP_NSS()
|
|
||||||
|
|
||||||
#endif // NSS_INIT_ENABLED
|
|
||||||
|
|
||||||
#endif // S3FS_S3_H_
|
#endif // S3FS_S3_H_
|
||||||
|
26
src/s3fs_auth.h
Normal file
26
src/s3fs_auth.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef S3FS_AUTH_H_
|
||||||
|
#define S3FS_AUTH_H_
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Utility functions for Authentication
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// in common_auth.cpp
|
||||||
|
//
|
||||||
|
char* s3fs_base64(unsigned char* input, size_t length);
|
||||||
|
std::string s3fs_get_content_md5(int fd);
|
||||||
|
std::string s3fs_md5sum(int fd, off_t start, ssize_t size);
|
||||||
|
|
||||||
|
//
|
||||||
|
// in xxxxxx_auth.cpp
|
||||||
|
//
|
||||||
|
const char* s3fs_crypt_lib_name(void);
|
||||||
|
bool s3fs_init_global_ssl(void);
|
||||||
|
bool s3fs_destroy_global_ssl(void);
|
||||||
|
bool s3fs_init_crypt_mutex(void);
|
||||||
|
bool s3fs_destroy_crypt_mutex(void);
|
||||||
|
bool s3fs_HMAC(const void* key, size_t keylen, const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen);
|
||||||
|
size_t get_md5_digest_length(void);
|
||||||
|
unsigned char* s3fs_md5hexsum(int fd, off_t start, ssize_t size);
|
||||||
|
|
||||||
|
#endif // S3FS_AUTH_H_
|
@ -41,6 +41,7 @@
|
|||||||
#include "s3fs_util.h"
|
#include "s3fs_util.h"
|
||||||
#include "string_util.h"
|
#include "string_util.h"
|
||||||
#include "s3fs.h"
|
#include "s3fs.h"
|
||||||
|
#include "s3fs_auth.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -997,11 +998,13 @@ void show_help (void)
|
|||||||
void show_version(void)
|
void show_version(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"Amazon Simple Storage Service File System %s\n"
|
"Amazon Simple Storage Service File System V%s with %s\n"
|
||||||
"Copyright (C) 2010 Randy Rizun <rrizun@gmail.com>\n"
|
"Copyright (C) 2010 Randy Rizun <rrizun@gmail.com>\n"
|
||||||
"License GPL2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>\n"
|
"License GPL2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>\n"
|
||||||
"This is free software: you are free to change and redistribute it.\n"
|
"This is free software: you are free to change and redistribute it.\n"
|
||||||
"There is NO WARRANTY, to the extent permitted by law.\n", VERSION );
|
"There is NO WARRANTY, to the extent permitted by law.\n",
|
||||||
|
VERSION, s3fs_crypt_lib_name());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// END
|
||||||
|
Loading…
Reference in New Issue
Block a user