From 6c9596b518a07f047af0fcc44bf666df0d66368d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Barab=C3=A1s?= Date: Tue, 14 Apr 2020 12:19:22 +0200 Subject: [PATCH] Make libetpan buildable on Android 23+, add client certificate authentication --- .gitignore | 2 +- autogen.sh | 0 build-android/build.sh | 19 +- .../dependencies/cyrus-sasl/build.sh | 16 +- build-android/dependencies/iconv/build.sh | 12 +- build-android/dependencies/openssl/build.sh | 4 +- build-android/jni/Android.mk | 7 +- build-mac/config-ios/config.h | 180 +++++++++++++++++ build-mac/config-ios/libetpan-config.h | 26 +++ build-mac/dependencies/prepare-cyrus-sasl.sh | 0 build-mac/libetpan.xcodeproj/project.pbxproj | 148 ++------------ .../xcschemes/libetpan ios.xcscheme | 11 +- .../xcschemes/libetpan-prepare-ios.xcscheme | 80 ++++++++ .../xcschemes/libetpan-prepare.xcscheme | 80 ++++++++ .../xcshareddata/xcschemes/libetpan.xcscheme | 11 +- .../xcschemes/static libetpan.xcscheme | 11 +- build-mac/update.sh | 0 build-windows/build_headers.list | 156 -------------- build-windows/gen-public-headers.sh | 0 build-windows/libetpan.sln | 104 +++++----- build-windows/libetpan_version.h | 15 +- configure.ac | 8 +- libetpan-config.h.in | 2 +- libetpan-config.in | 60 ++++++ libetpan.pc.in | 2 +- rules.mk | 20 +- src/android_log.h | 191 ++++++++++++++++++ src/data-types/carray.h | 2 +- src/data-types/extensions.c | 17 ++ src/data-types/extensions.h | 27 +++ src/data-types/mailstream.c | 23 +++ src/data-types/mailstream.h | 3 + src/data-types/mailstream_cfstream.c | 47 ++++- src/data-types/mailstream_socket.c | 32 +-- src/data-types/mailstream_ssl.c | 48 ++++- src/data-types/mailstream_ssl.h | 6 +- src/data-types/mailstream_types.h | 4 + src/low-level/imap/clientid.c | 1 - src/low-level/imap/mailimap.c | 24 +++ src/low-level/imap/mailimap.h | 6 +- src/low-level/imap/mailimap_sort.c | 9 +- src/low-level/imap/mailimap_sort.h | 3 - src/low-level/imap/mailimap_ssl.c | 22 ++ src/low-level/imap/mailimap_ssl.h | 2 +- src/low-level/imap/mailimap_types.h | 4 + src/low-level/imap/mailimap_types_helper.h | 4 +- src/low-level/imap/quota.h | 3 - src/low-level/imap/quota_parser.c | 36 ++-- src/low-level/mime/mailmime_write_generic.c | 34 ---- src/low-level/smtp/mailsmtp.c | 28 ++- src/low-level/smtp/mailsmtp.h | 5 +- src/low-level/smtp/mailsmtp_socket.c | 20 ++ src/low-level/smtp/mailsmtp_ssl.c | 33 +++ src/low-level/smtp/mailsmtp_types.h | 4 + src/main/libetpan_version.h.in | 13 -- tests/imap-sample.c | 2 +- travis/before-script.sh | 0 travis/script.sh | 0 58 files changed, 1099 insertions(+), 528 deletions(-) mode change 100755 => 100644 autogen.sh mode change 100755 => 100644 build-android/dependencies/cyrus-sasl/build.sh mode change 100755 => 100644 build-android/dependencies/iconv/build.sh mode change 100755 => 100644 build-android/dependencies/openssl/build.sh create mode 100644 build-mac/config-ios/config.h create mode 100644 build-mac/config-ios/libetpan-config.h mode change 100755 => 100644 build-mac/dependencies/prepare-cyrus-sasl.sh create mode 100644 build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan-prepare-ios.xcscheme create mode 100644 build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan-prepare.xcscheme mode change 100755 => 100644 build-mac/update.sh mode change 100755 => 100644 build-windows/gen-public-headers.sh create mode 100755 libetpan-config.in create mode 100644 src/android_log.h create mode 100644 src/data-types/extensions.c create mode 100644 src/data-types/extensions.h mode change 100755 => 100644 src/data-types/mailstream_cfstream.c mode change 100755 => 100644 travis/before-script.sh mode change 100755 => 100644 travis/script.sh diff --git a/.gitignore b/.gitignore index 22f11bba..83619170 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,7 @@ project.xcworkspace/ xcuserdata/ - +build-android/ /build-mac/autogen-result.md5 /build-mac/build /build-mac/include diff --git a/autogen.sh b/autogen.sh old mode 100755 new mode 100644 diff --git a/build-android/build.sh b/build-android/build.sh index 6388ca00..248f6b9a 100755 --- a/build-android/build.sh +++ b/build-android/build.sh @@ -8,6 +8,9 @@ package_name=libetpan-android current_dir="`pwd`" +# find ../src -name *.h | xargs -0 cp --target-directory=./include/libetpan +find ../src -name "*.h" -type file -exec cp {} ./include/libetpan \; + if test "x$ANDROID_NDK" = x ; then echo should set ANDROID_NDK before running this script. exit 1 @@ -62,14 +65,14 @@ mkdir -p "$current_dir/$package_name-$build_version/include" cp -r include/libetpan "$current_dir/$package_name-$build_version/include" # Start building. -ANDROID_PLATFORM=android-16 -archs="armeabi armeabi-v7a x86" -for arch in $archs ; do - TARGET_ARCH_ABI=$arch - build -done -ANDROID_PLATFORM=android-21 -archs="arm64-v8a" +#ANDROID_PLATFORM=android-16 +#archs="armeabi armeabi-v7a x86" +#for arch in $archs ; do + #TARGET_ARCH_ABI=$arch + #build +#done +ANDROID_PLATFORM=android-23 +archs="arm64-v8a armeabi-v7a x86 x86_64" for arch in $archs ; do TARGET_ARCH_ABI=$arch build diff --git a/build-android/dependencies/cyrus-sasl/build.sh b/build-android/dependencies/cyrus-sasl/build.sh old mode 100755 new mode 100644 index 3f5ef979..4cfafca6 --- a/build-android/dependencies/cyrus-sasl/build.sh +++ b/build-android/dependencies/cyrus-sasl/build.sh @@ -60,14 +60,14 @@ function build { } # Start building. -ANDROID_PLATFORM=android-16 -archs="armeabi armeabi-v7a x86" -for arch in $archs ; do - TARGET_ARCH_ABI=$arch - build -done -ANDROID_PLATFORM=android-21 -archs="arm64-v8a" +#ANDROID_PLATFORM=android-16 +#archs="armeabi armeabi-v7a x86" +#for arch in $archs ; do +# TARGET_ARCH_ABI=$arch +# build +#done +ANDROID_PLATFORM=android-23 +archs="arm64-v8a armeabi-v7a x86 x86_64" for arch in $archs ; do TARGET_ARCH_ABI=$arch build diff --git a/build-android/dependencies/iconv/build.sh b/build-android/dependencies/iconv/build.sh old mode 100755 new mode 100644 index d864722d..c7899e4c --- a/build-android/dependencies/iconv/build.sh +++ b/build-android/dependencies/iconv/build.sh @@ -46,16 +46,8 @@ if test ! -f $current_dir/$package_name-$build_version.zip; then mkdir -p "$current_dir/$package_name-$build_version" - # Start building. - ANDROID_PLATFORM=android-16 - archs="armeabi armeabi-v7a x86" - for arch in $archs ; do - TARGET_ARCH_ABI=$arch - build - done - - ANDROID_PLATFORM=android-21 - archs="arm64-v8a" + ANDROID_PLATFORM=android-23 + archs="arm64-v8a armeabi-v7a x86 x86_64" for arch in $archs ; do TARGET_ARCH_ABI=$arch build diff --git a/build-android/dependencies/openssl/build.sh b/build-android/dependencies/openssl/build.sh old mode 100755 new mode 100644 index 16903092..bb742826 --- a/build-android/dependencies/openssl/build.sh +++ b/build-android/dependencies/openssl/build.sh @@ -161,9 +161,11 @@ function build { # start building. current_dir="`pwd`" -build_armeabi + +#build_armeabi build_armeabi_v7a build_x86 +build_x86_64 build_arm64_v8a cd "$current_dir" diff --git a/build-android/jni/Android.mk b/build-android/jni/Android.mk index 037c2671..26a559e9 100644 --- a/build-android/jni/Android.mk +++ b/build-android/jni/Android.mk @@ -9,7 +9,6 @@ ifeq ($(CYRUS_SASL_PATH),) $(error CYRUS_SASL_PATH must be set) endif - ifeq ($(ICONV_PATH),) $(error ICONV_PATH must be set) endif @@ -144,7 +143,9 @@ src/driver/implementation/data-message \ src/driver/interface LOCAL_C_INCLUDES = $(addprefix ../../, $(c_includes)) \ - $(LOCAL_PATH)/../include $(LOCAL_PATH)/../include/libetpan \ - $(OPENSSL_PATH)/include $(CYRUS_SASL_PATH)/include $(ICONV_PATH)/include + libetpan-android-7/include \ + libetpan-android-7/include/libetpan \ + $(OPENSSL_PATH)/include \ + $(LOCAL_PATH)/../include $(LOCAL_PATH)/../include/libetpan include $(BUILD_STATIC_LIBRARY) diff --git a/build-mac/config-ios/config.h b/build-mac/config-ios/config.h new file mode 100644 index 00000000..efa3b248 --- /dev/null +++ b/build-mac/config-ios/config.h @@ -0,0 +1,180 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Check for Linux's /usr/include/features.h + */ +#ifdef _FEATURES_H +# error config.h must be first file included +#endif + +/* Define to detected Berkeley DB major version number */ +/* #undef DBVERS */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_CTYPE_H 1 + +/* Define to use curl */ +/* #undef HAVE_CURL */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to use expat */ +/* #undef HAVE_EXPAT */ + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to use getopt_long */ +#define HAVE_GETOPT_LONG 1 + +/* Define to 1 if you have the `getpagesize' function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the iconv() function. */ +/* #undef HAVE_ICONV */ + +/* prototype of iconv() has const parameters */ +/* #undef HAVE_ICONV_PROTO_CONST */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to enable IPv6 support. */ +#define HAVE_IPV6 1 + +/* Define to 1 if you have the `lockfile' library (-llockfile). */ +/* #undef HAVE_LIBLOCKFILE */ + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Defined if we run on a W32 API based system */ +/* #undef HAVE_MINGW32_SYSTEM */ + +/* Define to 1 if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NETDB_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PTHREAD_H 1 + +/* Define to use setenv */ +#define HAVE_SETENV 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINSOCK2_H */ + +/* Enable classes using zlib compression. */ +#define HAVE_ZLIB 1 + +/* Define to include multithreading support */ +#define LIBETPAN_REENTRANT 1 + +/* Define this to the version of libEtPan */ +#define LIBETPAN_VERSION "1.2-dev-20141203" + +/* Define this to the major version of libEtPan */ +#define LIBETPAN_VERSION_MAJOR 1 + +/* Define this to the minor version of libEtPan */ +#define LIBETPAN_VERSION_MINOR 2 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "libetpan" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "libetpan-devel@lists.sourceforge.net" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libetpan" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libetpan 1.2" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libetpan" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.2" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to be lazy on protocol syntax */ +#define UNSTRICT_SYNTAX 1 + +/* Define to use GnuTLS */ +/* #undef USE_GNUTLS */ + +/* Define to use SASL */ +#define USE_SASL 1 + +/* Define to use OpenSSL */ +// #define USE_SSL 1 + +/* Version number of package */ +#define VERSION "1.2" + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif diff --git a/build-mac/config-ios/libetpan-config.h b/build-mac/config-ios/libetpan-config.h new file mode 100644 index 00000000..0bf45f42 --- /dev/null +++ b/build-mac/config-ios/libetpan-config.h @@ -0,0 +1,26 @@ +#ifndef LIBETPAN_CONFIG_H +#define LIBETPAN_CONFIG_H +#if WIN32 +# define MMAP_UNAVAILABLE +#endif +#ifdef _MSC_VER +# define inline __inline +#endif +#include +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif +#include +#include +#define MAIL_DIR_SEPARATOR '/' +#define MAIL_DIR_SEPARATOR_S "/" +#ifdef _MSC_VER +# ifdef LIBETPAN_DLL +# define LIBETPAN_EXPORT __declspec(dllexport) +# else +# define LIBETPAN_EXPORT __declspec(dllimport) +# endif +#else +# define LIBETPAN_EXPORT +#endif +#endif diff --git a/build-mac/dependencies/prepare-cyrus-sasl.sh b/build-mac/dependencies/prepare-cyrus-sasl.sh old mode 100755 new mode 100644 diff --git a/build-mac/libetpan.xcodeproj/project.pbxproj b/build-mac/libetpan.xcodeproj/project.pbxproj index 6d9fae0a..3ee572d0 100644 --- a/build-mac/libetpan.xcodeproj/project.pbxproj +++ b/build-mac/libetpan.xcodeproj/project.pbxproj @@ -548,30 +548,6 @@ C6F9EDB2105339650059C3BA /* libcurl.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C6F9EDB1105339650059C3BA /* libcurl.dylib */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - C6635C4716E000310066276E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = C6635C4316DFFE6E0066276E; - remoteInfo = "libetpan-prepare"; - }; - C6635C4916E000340066276E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = C6635C4316DFFE6E0066276E; - remoteInfo = "libetpan-prepare"; - }; - C6635C5116E0027B0066276E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = C6635C4D16E002340066276E; - remoteInfo = "libetpan-prepare-ios"; - }; -/* End PBXContainerItemProxy section */ - /* Begin PBXFileReference section */ 2307A00A170AAA5500C43C59 /* mailstream_compress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mailstream_compress.c; sourceTree = ""; }; 2307A00B170AAA5500C43C59 /* mailstream_compress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mailstream_compress.h; sourceTree = ""; }; @@ -1705,37 +1681,6 @@ }; /* End PBXGroup section */ -/* Begin PBXLegacyTarget section */ - C6635C4316DFFE6E0066276E /* libetpan-prepare */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "$(SRCROOT)/update.sh"; - buildConfigurationList = C6635C4416DFFE6E0066276E /* Build configuration list for PBXLegacyTarget "libetpan-prepare" */; - buildPhases = ( - ); - buildToolPath = /bin/sh; - buildWorkingDirectory = "$(SRCROOT)"; - dependencies = ( - ); - name = "libetpan-prepare"; - passBuildSettingsInEnvironment = 1; - productName = "libetpan-prepare"; - }; - C6635C4D16E002340066276E /* libetpan-prepare-ios */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "$(SRCROOT)/update.sh"; - buildConfigurationList = C6635C4E16E002340066276E /* Build configuration list for PBXLegacyTarget "libetpan-prepare-ios" */; - buildPhases = ( - ); - buildToolPath = /bin/sh; - buildWorkingDirectory = "$(SRCROOT)"; - dependencies = ( - ); - name = "libetpan-prepare-ios"; - passBuildSettingsInEnvironment = 1; - productName = "libetpan-prepare"; - }; -/* End PBXLegacyTarget section */ - /* Begin PBXNativeTarget section */ 8DC2EF4F0486A6940098B216 /* libetpan */ = { isa = PBXNativeTarget; @@ -1749,7 +1694,6 @@ buildRules = ( ); dependencies = ( - C6635C4816E000310066276E /* PBXTargetDependency */, ); name = libetpan; productInstallPath = "$(HOME)/Library/Frameworks"; @@ -1769,7 +1713,6 @@ buildRules = ( ); dependencies = ( - C6635C5216E0027B0066276E /* PBXTargetDependency */, ); name = "libetpan ios"; productName = "static libetpan"; @@ -1787,7 +1730,6 @@ buildRules = ( ); dependencies = ( - C6635C4A16E000340066276E /* PBXTargetDependency */, ); name = "static libetpan"; productName = "static libetpan"; @@ -1820,8 +1762,6 @@ 8DC2EF4F0486A6940098B216 /* libetpan */, C69AB10910546FE500F32FBD /* static libetpan */, C682E21815B315EF00BE9DA7 /* libetpan ios */, - C6635C4316DFFE6E0066276E /* libetpan-prepare */, - C6635C4D16E002340066276E /* libetpan-prepare-ios */, ); }; /* End PBXProject section */ @@ -1887,7 +1827,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "cp \"$SRCROOT/libsasl-ios/lib/libsasl2.a\" \"$BUILT_PRODUCTS_DIR\"\n"; + shellScript = "#cp \"$SRCROOT/libsasl-ios/lib/libsasl2.a\" \"$BUILT_PRODUCTS_DIR\"\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -2446,24 +2386,6 @@ }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - C6635C4816E000310066276E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = C6635C4316DFFE6E0066276E /* libetpan-prepare */; - targetProxy = C6635C4716E000310066276E /* PBXContainerItemProxy */; - }; - C6635C4A16E000340066276E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = C6635C4316DFFE6E0066276E /* libetpan-prepare */; - targetProxy = C6635C4916E000340066276E /* PBXContainerItemProxy */; - }; - C6635C5216E0027B0066276E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = C6635C4D16E002340066276E /* libetpan-prepare-ios */; - targetProxy = C6635C5116E0027B0066276E /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin XCBuildConfiguration section */ 1DEB91AE08733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; @@ -2477,11 +2399,16 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; + HEADER_SEARCH_PATHS = ( + "$(SRCROOT)/..", + "$(SRCROOT)/include", + ); INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@loader_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.8; PRODUCT_NAME = libetpan; SDKROOT = macosx; + SYSTEM_HEADER_SEARCH_PATHS = ""; WRAPPER_EXTENSION = framework; }; name = Debug; @@ -2496,12 +2423,17 @@ DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; GCC_MODEL_TUNING = G5; + HEADER_SEARCH_PATHS = ( + "$(SRCROOT)/..", + "$(SRCROOT)/include", + ); INFOPLIST_FILE = Info.plist; INSTALL_PATH = "@loader_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.8; PRODUCT_NAME = libetpan; SDKROOT = macosx; STRIP_INSTALLED_PRODUCT = YES; + SYSTEM_HEADER_SEARCH_PATHS = ""; WRAPPER_EXTENSION = framework; }; name = Release; @@ -2517,6 +2449,8 @@ HEADER_SEARCH_PATHS = ( "$(SRCROOT)/..", "$(SRCROOT)/include", + "$(SRCROOT)/../include", + "$(SRCROOT)/../include/libetpan", ); ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( @@ -2537,6 +2471,8 @@ HEADER_SEARCH_PATHS = ( "$(SRCROOT)/..", "$(SRCROOT)/include", + "$(SRCROOT)/../include", + "$(SRCROOT)/../include/libetpan", ); OTHER_CFLAGS = ( "-DHAVE_CFNETWORK=1", @@ -2546,36 +2482,6 @@ }; name = Release; }; - C6635C4516DFFE6E0066276E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - SDKROOT = macosx; - }; - name = Debug; - }; - C6635C4616DFFE6E0066276E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - SDKROOT = macosx; - }; - name = Release; - }; - C6635C4F16E002340066276E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PLATFORM_NAME = iphoneos; - SDKROOT = iphoneos; - }; - name = Debug; - }; - C6635C5016E002340066276E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PLATFORM_NAME = iphoneos; - SDKROOT = iphoneos; - }; - name = Release; - }; C682E2BE15B315EF00BE9DA7 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2588,13 +2494,16 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/libsasl-ios/include", + "$(SRCROOT)/../../../libsasl-ios/include", ); INSTALL_PATH = /usr/local/lib; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LIBRARY_SEARCH_PATHS = "$(SRCROOT)/libsasl-ios/lib"; + ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "etpan-ios"; SDKROOT = iphoneos; SKIP_INSTALL = YES; + VALID_ARCHS = "arm64 armv7 x86_64"; }; name = Debug; }; @@ -2609,13 +2518,16 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)/libsasl-ios/include", + "$(SRCROOT)/../../../libsasl-ios/include", ); INSTALL_PATH = /usr/local/lib; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LIBRARY_SEARCH_PATHS = "$(SRCROOT)/libsasl-ios/lib"; + ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "etpan-ios"; SDKROOT = iphoneos; SKIP_INSTALL = YES; + VALID_ARCHS = "arm64 armv7 x86_64"; ZERO_LINK = NO; }; name = Release; @@ -2675,24 +2587,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - C6635C4416DFFE6E0066276E /* Build configuration list for PBXLegacyTarget "libetpan-prepare" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C6635C4516DFFE6E0066276E /* Debug */, - C6635C4616DFFE6E0066276E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C6635C4E16E002340066276E /* Build configuration list for PBXLegacyTarget "libetpan-prepare-ios" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C6635C4F16E002340066276E /* Debug */, - C6635C5016E002340066276E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; C682E2BD15B315EF00BE9DA7 /* Build configuration list for PBXNativeTarget "libetpan ios" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan ios.xcscheme b/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan ios.xcscheme index 5a7c3c90..bc533a08 100644 --- a/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan ios.xcscheme +++ b/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan ios.xcscheme @@ -23,21 +23,24 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan-prepare.xcscheme b/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan-prepare.xcscheme new file mode 100644 index 00000000..99231a71 --- /dev/null +++ b/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan-prepare.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan.xcscheme b/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan.xcscheme index aba37d0b..eb3b0e5c 100644 --- a/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan.xcscheme +++ b/build-mac/libetpan.xcodeproj/xcshareddata/xcschemes/libetpan.xcscheme @@ -23,21 +23,24 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> + + + shouldUseLaunchSchemeArgsEnv = "YES"> + + &2 + exit 1 +fi + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + if test $exec_prefix_set = no ; then + exec_prefix=$optarg + fi + ;; + --prefix) + echo $prefix + ;; + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + ;; + --exec-prefix) + echo $exec_prefix + ;; + --version) + echo @VERSION@ + ;; + --cflags) + if test "@includedir@" = "/usr/include" ; then + includedir="" + else + includedir=-I@includedir@ + fi + echo $includedir + ;; + --libs) + libdir=-L@libdir@ + echo $libdir -letpan@LIBSUFFIX@ @LDFLAGS@ @SSLLIBS@ @GNUTLSLIB@ @LIBICONV@ @DBLIB@ @LIBS@ @SASLLIBS@ + ;; + *) + echo "${usage}" 1>&2 + exit 1 + ;; + esac + shift +done + diff --git a/libetpan.pc.in b/libetpan.pc.in index e0dc7742..cbc1d2c4 100644 --- a/libetpan.pc.in +++ b/libetpan.pc.in @@ -6,5 +6,5 @@ libdir=@libdir@ Name: libetpan Description: Libetpan C library. Version: @VERSION@ -Libs: -L${libdir} -letpan@LIBSUFFIX@ @SSLLIBS@ @GNUTLSLIB@ @LIBICONV@ @DBLIB@ @LIBS@ @SASLLIBS@ +Libs: -L${libdir} -letpan@LIBSUFFIX@ @LDFLAGS@ @SSLLIBS@ @GNUTLSLIB@ @LIBICONV@ @DBLIB@ @LIBS@ @SASLLIBS@ Cflags: -I${includedir} diff --git a/rules.mk b/rules.mk index ae22e882..eec8b346 100644 --- a/rules.mk +++ b/rules.mk @@ -127,20 +127,20 @@ prepare-am: prepare-local @if test "$(etpaninclude_HEADERS)" != ""; then \ echo "$(mkinstalldirs) $(top_builddir)/include/libetpan/"; \ $(mkinstalldirs) $(top_builddir)/include/libetpan/;\ - echo "cd $(top_builddir)/include/libetpan/"; \ - cd $(top_builddir)/include/libetpan/ \ - && for hdr in $(etpaninclude_HEADERS) list_end; do \ + echo "cd $(top_builddir)/include/libetpan/"; \ + cd $(top_builddir)/include/libetpan/ \ + && for hdr in $(etpaninclude_HEADERS) list_end; do \ if test $${hdr} != list_end; then \ - if test -e $(abs_srcdir)/$${hdr}; then \ - echo "$(LN_S) -f $(abs_srcdir)/$${hdr} ."; \ - $(LN_S) -f $(abs_srcdir)/$${hdr} .; \ + if test -e ../../$(subdir)/$${hdr}; then \ + echo "$(LN_S) -f ../../$(subdir)/$${hdr} ."; \ + $(LN_S) -f ../../$(subdir)/$${hdr} .; \ else \ - echo "$(LN_S) -f $(abs_builddir)/$${hdr} ."; \ - $(LN_S) -f $(abs_builddir)/$${hdr} .; \ + echo "$(LN_S) -f ../../$(subdir)/$(srcdir)/$${hdr} ."; \ + $(LN_S) -f ../../$(subdir)/$(srcdir)/$${hdr} .; \ fi; \ fi; \ - done; \ - fi + done; \ + fi # Use this target to extend the prepare rules in a single Makefile.am. prepare-local: diff --git a/src/android_log.h b/src/android_log.h new file mode 100644 index 00000000..ee9220d4 --- /dev/null +++ b/src/android_log.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_LOG_H +#define _ANDROID_LOG_H + +/****************************************************************** + * + * IMPORTANT NOTICE: + * + * This file is part of Android's set of stable system headers + * exposed by the Android NDK (Native Development Kit) since + * platform release 1.5 + * + * Third-party source AND binary code relies on the definitions + * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES. + * + * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES) + * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS + * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY + * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES + */ + +/** + * @addtogroup Logging + * @{ + */ + +/** + * \file + * + * Support routines to send messages to the Android log buffer, + * which can later be accessed through the `logcat` utility. + * + * Each log message must have + * - a priority + * - a log tag + * - some text + * + * The tag normally corresponds to the component that emits the log message, + * and should be reasonably small. + * + * Log message text may be truncated to less than an implementation-specific + * limit (1023 bytes). + * + * Note that a newline character ("\n") will be appended automatically to your + * log message, if not already there. It is not possible to send several + * messages and have them appear on a single line in logcat. + * + * Please use logging in moderation: + * + * - Sending log messages eats CPU and slow down your application and the + * system. + * + * - The circular log buffer is pretty small, so sending many messages + * will hide other important log messages. + * + * - In release builds, only send log messages to account for exceptional + * conditions. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Android log priority values, in increasing order of priority. + */ +typedef enum android_LogPriority { + /** For internal use only. */ + ANDROID_LOG_UNKNOWN = 0, + /** The default priority, for internal use only. */ + ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ + /** Verbose logging. Should typically be disabled for a release apk. */ + ANDROID_LOG_VERBOSE, + /** Debug logging. Should typically be disabled for a release apk. */ + ANDROID_LOG_DEBUG, + /** Informational logging. Should typically be disabled for a release apk. */ + ANDROID_LOG_INFO, + /** Warning logging. For use with recoverable failures. */ + ANDROID_LOG_WARN, + /** Error logging. For use with unrecoverable failures. */ + ANDROID_LOG_ERROR, + /** Fatal logging. For use when aborting. */ + ANDROID_LOG_FATAL, + /** For internal use only. */ + ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ +} android_LogPriority; + +/** + * Writes the constant string `text` to the log, with priority `prio` and tag + * `tag`. + */ +int __android_log_write(int prio, const char* tag, const char* text); + +/** + * Writes a formatted string to the log, with priority `prio` and tag `tag`. + * The details of formatting are the same as for + * [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html). + */ +int __android_log_print(int prio, const char* tag, const char* fmt, ...) +#if defined(__GNUC__) + __attribute__((__format__(printf, 3, 4))) +#endif + ; + +/** + * Equivalent to `__android_log_print`, but taking a `va_list`. + * (If `__android_log_print` is like `printf`, this is like `vprintf`.) + */ +int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) +#if defined(__GNUC__) + __attribute__((__format__(printf, 3, 0))) +#endif + ; + +/** + * Writes an assertion failure to the log (as `ANDROID_LOG_FATAL`) and to + * stderr, before calling + * [abort(3)](http://man7.org/linux/man-pages/man3/abort.3.html). + * + * If `fmt` is non-null, `cond` is unused. If `fmt` is null, the string + * `Assertion failed: %s` is used with `cond` as the string argument. + * If both `fmt` and `cond` are null, a default string is provided. + * + * Most callers should use + * [assert(3)](http://man7.org/linux/man-pages/man3/assert.3.html) from + * `` instead, or the `__assert` and `__assert2` functions provided by + * bionic if more control is needed. They support automatically including the + * source filename and line number more conveniently than this function. + */ +void __android_log_assert(const char* cond, const char* tag, const char* fmt, + ...) +#if defined(__GNUC__) + __attribute__((__noreturn__)) + __attribute__((__format__(printf, 3, 4))) +#endif + ; + +#ifndef log_id_t_defined +#define log_id_t_defined +typedef enum log_id { + LOG_ID_MIN = 0, + + LOG_ID_MAIN = 0, + LOG_ID_RADIO = 1, + LOG_ID_EVENTS = 2, + LOG_ID_SYSTEM = 3, + LOG_ID_CRASH = 4, + LOG_ID_STATS = 5, + LOG_ID_SECURITY = 6, + LOG_ID_KERNEL = 7, /* place last, third-parties can not use it */ + + LOG_ID_MAX +} log_id_t; +#endif + +/* + * Send a simple string to the log. + */ +int __android_log_buf_write(int bufID, int prio, const char* tag, + const char* text); +int __android_log_buf_print(int bufID, int prio, const char* tag, + const char* fmt, ...) +#if defined(__GNUC__) + __attribute__((__format__(printf, 4, 5))) +#endif + ; + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* _ANDROID_LOG_H */ diff --git a/src/data-types/carray.h b/src/data-types/carray.h index ed5a875f..5cca4835 100644 --- a/src/data-types/carray.h +++ b/src/data-types/carray.h @@ -3,7 +3,7 @@ * * carray - Implements simple dynamic pointer arrays * - * Copyright (c) 1999-2005, Ga�l Roualland + * Copyright (c) 1999-2005, Ga�l Roualland * interface changes - 2005 - DINH Viet Hoa * All rights reserved. * diff --git a/src/data-types/extensions.c b/src/data-types/extensions.c new file mode 100644 index 00000000..5cc89bce --- /dev/null +++ b/src/data-types/extensions.c @@ -0,0 +1,17 @@ +#include "extensions.h" + +struct domain_pindata_pair_entry * domain_pindata_pair_entry_block = 0; +int domain_pindata_pair_entry_count = 0; + +void set_domain_pindata_pairs(struct domain_pindata_pair_entry * pair_entries, int entry_count) +{ + domain_pindata_pair_entry_block = pair_entries; + domain_pindata_pair_entry_count = entry_count; +} + +void set_client_certificate(char * certificate) +{ + +} + + diff --git a/src/data-types/extensions.h b/src/data-types/extensions.h new file mode 100644 index 00000000..390def05 --- /dev/null +++ b/src/data-types/extensions.h @@ -0,0 +1,27 @@ + +#ifndef EXTENSIONS_H + +#define EXTENSIONS_H + +#ifdef __cplusplus +extern "C" { +#endif + + +struct domain_pindata_pair_entry +{ + char* domain; + char* pin_data; +}; + +void set_domain_pindata_pairs(struct domain_pindata_pair_entry * pair_entries, int entry_count); +void set_client_certificate(char * certificate); + +#ifdef __cplusplus +} +#endif + + +#endif + + diff --git a/src/data-types/mailstream.c b/src/data-types/mailstream.c index 11b17356..3f567fe5 100644 --- a/src/data-types/mailstream.c +++ b/src/data-types/mailstream.c @@ -84,6 +84,10 @@ mailstream * mailstream_new(mailstream_low * low, size_t buffer_size) s->logger = NULL; s->logger_context = NULL; + s->client_cert_length = 0; + s->client_cert = NULL; + s->client_cert_password = NULL; + mailstream_set_low(s, low); return s; @@ -130,6 +134,22 @@ static ssize_t write_direct(mailstream * s, const void * buf, size_t count) return count; } +LIBETPAN_EXPORT +void mailstream_set_client_cert(mailstream * s, const void * buf, size_t count, const char* password) +{ + free(s->client_cert); + s->client_cert_length = count; + s->client_cert = malloc(count); + if(s->client_cert) + memcpy(s->client_cert, buf, count); + + size_t len = strlen(password); + free(s->client_cert_password); + s->client_cert_password = malloc(len + 1); + if(s->client_cert_password) + strcpy(s->client_cert_password, password); +} + LIBETPAN_EXPORT ssize_t mailstream_write(mailstream * s, const void * buf, size_t count) { @@ -287,6 +307,9 @@ int mailstream_close(mailstream * s) free(s->read_buffer); free(s->write_buffer); + free(s->client_cert); + free(s->client_cert_password); + free(s); return 0; diff --git a/src/data-types/mailstream.h b/src/data-types/mailstream.h index 95f3a4b0..d0145521 100644 --- a/src/data-types/mailstream.h +++ b/src/data-types/mailstream.h @@ -58,6 +58,9 @@ mailstream * mailstream_new(mailstream_low * low, size_t buffer_size); LIBETPAN_EXPORT ssize_t mailstream_write(mailstream * s, const void * buf, size_t count); +LIBETPAN_EXPORT +void mailstream_set_client_cert(mailstream * s, const void * buf, size_t count, const char* password); + LIBETPAN_EXPORT ssize_t mailstream_read(mailstream * s, void * buf, size_t count); diff --git a/src/data-types/mailstream_cfstream.c b/src/data-types/mailstream_cfstream.c old mode 100755 new mode 100644 index 7212ec38..136febed --- a/src/data-types/mailstream_cfstream.c +++ b/src/data-types/mailstream_cfstream.c @@ -675,6 +675,13 @@ enum { WAIT_RUNLOOP_EXIT_TIMEOUT, }; +unsigned delta(unsigned position) { + if (position == 0 || position == 1) + return position; + else + return delta(position-1) + delta(position-2); +} + static int wait_runloop(mailstream_low * s, int wait_state) { struct mailstream_cfstream_data * cfstream_data; @@ -990,11 +997,40 @@ int mailstream_cfstream_set_ssl_enabled(mailstream * s, int ssl_enabled) CFDictionarySetValue(settings, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse); } - CFReadStreamSetProperty(cfstream_data->readStream, kCFStreamPropertySSLSettings, settings); - CFWriteStreamSetProperty(cfstream_data->writeStream, kCFStreamPropertySSLSettings, settings); + if(s->client_cert && s->client_cert_password) + { + CFDataRef certdata = CFDataCreate(NULL, s->client_cert, s->client_cert_length); + + CFStringRef password = CFStringCreateWithCString(NULL, s->client_cert_password, kCFStringEncodingUTF8); + + CFMutableDictionaryRef pkcs12options = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(pkcs12options, kSecImportExportPassphrase, password); + CFArrayRef pkcs12out; + + OSStatus status = SecPKCS12Import(certdata, pkcs12options, &pkcs12out); + if(!status) + { + CFDictionaryRef identityDict = CFArrayGetValueAtIndex(pkcs12out, 0); + SecIdentityRef identityRef = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); + + SecCertificateRef cert = NULL; + OSStatus status = SecIdentityCopyCertificate(identityRef, &cert); + if (!status) + { + CFMutableArrayRef array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + CFArrayAppendValue(array, identityRef); + CFArrayAppendValue(array, cert); + CFDictionarySetValue(settings, kCFStreamSSLCertificates, array); + } + } + } + + Boolean res = CFReadStreamSetProperty(cfstream_data->readStream, kCFStreamPropertySSLSettings, settings); + res = CFWriteStreamSetProperty(cfstream_data->writeStream, kCFStreamPropertySSLSettings, settings); CFRelease(settings); } - else { + else + { CFMutableDictionaryRef settings; settings = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -1269,3 +1305,8 @@ static carray * mailstream_low_cfstream_get_certificate_chain(mailstream_low * s return NULL; #endif } + +void LocalDebuggableBuildTest() +{ + printf("LocalDebuggableBuildTest()\n"); +} diff --git a/src/data-types/mailstream_socket.c b/src/data-types/mailstream_socket.c index 69591eb6..9ad64d73 100644 --- a/src/data-types/mailstream_socket.c +++ b/src/data-types/mailstream_socket.c @@ -205,7 +205,6 @@ static int mailstream_low_socket_get_fd(mailstream_low * s) static ssize_t mailstream_low_socket_read(mailstream_low * s, void * buf, size_t count) { - int r; struct mailstream_socket_data * socket_data; socket_data = (struct mailstream_socket_data *) s->data; @@ -216,6 +215,7 @@ static ssize_t mailstream_low_socket_read(mailstream_low * s, /* timeout */ { struct timeval timeout; + int r; int cancellation_fd; int cancelled; int got_data; @@ -296,29 +296,16 @@ static ssize_t mailstream_low_socket_read(mailstream_low * s, } if (socket_data->use_read) { - r = read(socket_data->fd, buf, count); + return read(socket_data->fd, buf, count); } else { - r = recv(socket_data->fd, buf, count, 0); -#ifdef WIN32 - if (SOCKET_ERROR == r) { - if (WSAEWOULDBLOCK == WSAGetLastError()) { - r = 0; - } - } else if (r == 0 && count > 0) { - /* The socket is gracefully closed */ - r = SOCKET_ERROR; - } -#endif + return recv(socket_data->fd, buf, count, 0); } - - return r; } static ssize_t mailstream_low_socket_write(mailstream_low * s, const void * buf, size_t count) { - int r; struct mailstream_socket_data * socket_data; socket_data = (struct mailstream_socket_data *) s->data; @@ -329,6 +316,7 @@ static ssize_t mailstream_low_socket_write(mailstream_low * s, /* timeout */ { struct timeval timeout; + int r; int cancellation_fd; int cancelled; int write_enabled; @@ -411,17 +399,7 @@ static ssize_t mailstream_low_socket_write(mailstream_low * s, return 0; } - r = send(socket_data->fd, buf, count, 0); - -#ifdef WIN32 - if (SOCKET_ERROR == r) { - if (WSAEWOULDBLOCK == WSAGetLastError()) { - r = 0; - } - } -#endif - - return r; + return send(socket_data->fd, buf, count, 0); } diff --git a/src/data-types/mailstream_ssl.c b/src/data-types/mailstream_ssl.c index 970c892c..30e65526 100644 --- a/src/data-types/mailstream_ssl.c +++ b/src/data-types/mailstream_ssl.c @@ -87,6 +87,7 @@ #ifdef USE_SSL # ifndef USE_GNUTLS # include +# include # else # include # include @@ -100,6 +101,7 @@ void mailprivacy_smime_init_lock(); # endif # endif + #endif #include "mmapstring.h" @@ -636,7 +638,7 @@ static struct mailstream_ssl_data * ssl_data_new(int fd, time_t timeout, timeout_value = mailstream_network_delay.tv_sec * 1000 + mailstream_network_delay.tv_usec / 1000; } else { - timeout_value = timeout * 1000; + timeout_value = timeout; } #if GNUTLS_VERSION_NUMBER >= 0x030100 gnutls_handshake_set_timeout(session, timeout_value); @@ -1267,6 +1269,48 @@ mailstream_low * mailstream_low_tls_open_with_callback_timeout(int fd, time_t ti return mailstream_low_ssl_open_full(fd, 1, timeout, callback, data); } +int mailstream_ssl_set_client_certicate_data(struct mailstream_ssl_context * ssl_context, + unsigned char* data, size_t length, const char* password) +{ +#ifdef USE_SSL +#ifdef USE_GNUTLS + /* not implemented */ + return -1; +#else + PKCS12* pkcs12; + unsigned char* certData = (unsigned char*)data; + long certLen = (long)length; + + EVP_PKEY *pkey_; + X509 *cert; + STACK_OF(X509) *ca = NULL; + const char* password_ = password; + + if(password_ && *password_ == 0) + password_ = NULL; + + pkcs12 = d2i_PKCS12(NULL,(const unsigned char**)&certData, certLen); + if(pkcs12) + { + if(PKCS12_parse(pkcs12, password_, &pkey_, &cert, &ca)) + { + + if(cert && pkey_) + { + ssl_context->client_x509 = cert; + ssl_context->client_pkey = pkey_; + return 0; + } + } + } + + return -1; + #endif + #else + return -1; + #endif +} + int mailstream_ssl_set_client_certicate(struct mailstream_ssl_context * ssl_context, char * filename) { @@ -1293,7 +1337,7 @@ int mailstream_ssl_set_client_certicate(struct mailstream_ssl_context * ssl_cont } LIBETPAN_EXPORT -int mailstream_ssl_set_client_certificate_data(struct mailstream_ssl_context * ssl_context, +int mailstream_ssl_set_client_cert_data(struct mailstream_ssl_context * ssl_context, unsigned char *x509_der, size_t len) { #ifdef USE_SSL diff --git a/src/data-types/mailstream_ssl.h b/src/data-types/mailstream_ssl.h index fbf2642a..349c2c3b 100644 --- a/src/data-types/mailstream_ssl.h +++ b/src/data-types/mailstream_ssl.h @@ -114,7 +114,11 @@ int mailstream_ssl_set_client_certicate(struct mailstream_ssl_context * ssl_cont char * file_name); LIBETPAN_EXPORT -int mailstream_ssl_set_client_certificate_data(struct mailstream_ssl_context * ssl_context, +int mailstream_ssl_set_client_certicate_data(struct mailstream_ssl_context * ssl_context, + unsigned char* data, size_t length, const char* password); + +LIBETPAN_EXPORT +int mailstream_ssl_set_client_cert_data(struct mailstream_ssl_context * ssl_context, unsigned char *x509_der, size_t len); int mailstream_ssl_set_client_private_key_data(struct mailstream_ssl_context * ssl_context, unsigned char *pkey_der, size_t len); diff --git a/src/data-types/mailstream_types.h b/src/data-types/mailstream_types.h index 02edccf1..ac04c35c 100644 --- a/src/data-types/mailstream_types.h +++ b/src/data-types/mailstream_types.h @@ -87,6 +87,10 @@ struct _mailstream { void (* logger)(mailstream * s, int log_type, const char * str, size_t size, void * logger_context); void * logger_context; + + void* client_cert; + size_t client_cert_length; + char * client_cert_password; }; struct mailstream_low_driver { diff --git a/src/low-level/imap/clientid.c b/src/low-level/imap/clientid.c index 8221a329..38880dd3 100644 --- a/src/low-level/imap/clientid.c +++ b/src/low-level/imap/clientid.c @@ -33,7 +33,6 @@ # include #endif -#include #include #include "mailimap_sender.h" diff --git a/src/low-level/imap/mailimap.c b/src/low-level/imap/mailimap.c index 0921a7fa..6d694293 100644 --- a/src/low-level/imap/mailimap.c +++ b/src/low-level/imap/mailimap.c @@ -970,6 +970,10 @@ int mailimap_close(mailimap * session) struct mailimap_response * response; int r; int error_code; + + free(session->client_cert); + session->client_cert_length = 0; + free(session->client_cert_password); if (session->imap_state != MAILIMAP_STATE_SELECTED) return MAILIMAP_ERROR_BAD_STATE; @@ -2621,6 +2625,10 @@ mailimap * mailimap_new(size_t imap_progr_rate, f = malloc(sizeof(* f)); if (f == NULL) goto err; + + f->client_cert = NULL; + f->client_cert_length = 0; + f->client_cert_password = NULL; f->imap_response = NULL; @@ -2797,3 +2805,19 @@ LIBETPAN_EXPORT int mailimap_is_qip_workaround_enabled(mailimap * session) { return session->is_qip_workaround_enabled; } + +LIBETPAN_EXPORT +void mailimap_set_client_cert(mailimap * s, unsigned char* data, size_t count, const char* password) +{ + free(s->client_cert); + s->client_cert_length = count; + s->client_cert = malloc(count); + if(s->client_cert) + memcpy(s->client_cert, data, count); + + size_t len = strlen(password); + free(s->client_cert_password); + s->client_cert_password = malloc(len + 1); + if(s->client_cert_password) + strcpy(s->client_cert_password, password); +} diff --git a/src/low-level/imap/mailimap.h b/src/low-level/imap/mailimap.h index 537a236b..deca8a29 100644 --- a/src/low-level/imap/mailimap.h +++ b/src/low-level/imap/mailimap.h @@ -344,7 +344,7 @@ mailimap_fetch(mailimap * session, struct mailimap_set * set, struct mailimap_fetch_type * fetch_type, clist ** result); /* - mailimap_uid_fetch() + mailimap_fetch() This function will retrieve data associated with the given message numbers. @@ -866,6 +866,10 @@ time_t mailimap_get_timeout(mailimap * session); @return the value of the timeout in seconds. */ + +LIBETPAN_EXPORT +void mailimap_set_client_cert(mailimap * session, unsigned char* data, size_t length, const char* password); + LIBETPAN_EXPORT void mailimap_set_logger(mailimap * session, void (* logger)(mailimap * session, int log_type, const char * str, size_t size, void * context), void * logger_context); diff --git a/src/low-level/imap/mailimap_sort.c b/src/low-level/imap/mailimap_sort.c index 7291f7d3..b6448e95 100644 --- a/src/low-level/imap/mailimap_sort.c +++ b/src/low-level/imap/mailimap_sort.c @@ -135,7 +135,7 @@ mailimap_sort(mailimap * session, const char * charset, session->imap_response_info->rsp_extension_list = NULL; if (sort_result == NULL) { - sort_result = clist_new(); + return MAILIMAP_ERROR_EXTENSION; } error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; @@ -213,7 +213,7 @@ mailimap_uid_sort(mailimap * session, const char * charset, session->imap_response_info->rsp_extension_list = NULL; if (sort_result == NULL) { - sort_result = clist_new(); + return MAILIMAP_ERROR_EXTENSION; } error_code = response->rsp_resp_done->rsp_data.rsp_tagged->rsp_cond_state->rsp_type; @@ -449,8 +449,3 @@ mailimap_sort_extension_data_free(struct mailimap_extension_data * ext_data) free(ext_data); } -LIBETPAN_EXPORT -int mailimap_has_sort(mailimap * session) -{ - return mailimap_has_extension(session, "SORT"); -} diff --git a/src/low-level/imap/mailimap_sort.h b/src/low-level/imap/mailimap_sort.h index ab0a1506..841f823e 100644 --- a/src/low-level/imap/mailimap_sort.h +++ b/src/low-level/imap/mailimap_sort.h @@ -95,9 +95,6 @@ extern "C" { LIBETPAN_EXPORT void mailimap_sort_result_free(clist * search_result); - LIBETPAN_EXPORT - int mailimap_has_sort(mailimap * session); - #ifdef __cplusplus } #endif diff --git a/src/low-level/imap/mailimap_ssl.c b/src/low-level/imap/mailimap_ssl.c index 2e0029da..4ea1374a 100644 --- a/src/low-level/imap/mailimap_ssl.c +++ b/src/low-level/imap/mailimap_ssl.c @@ -111,8 +111,26 @@ int mailimap_ssl_connect(mailimap * f, const char * server, uint16_t port) return mailimap_ssl_connect_voip(f, server, port, mailstream_cfstream_voip_enabled); } +void mailimap_ssl_connect_callback_ccert(struct mailstream_ssl_context * ssl_context, void * data) +{ + mailimap * f = (mailimap*)data; + + if(f->client_cert && f->client_cert_length && f->client_cert_password) + { + mailstream_ssl_set_client_certicate_data(ssl_context, f->client_cert, f->client_cert_length, f->client_cert_password); + } +} + int mailimap_ssl_connect_voip(mailimap * f, const char * server, uint16_t port, int voip_enabled) { +#if defined(ANDROID) || defined(__ANDROID__) + if(f->client_cert && f->client_cert_password) + { + return mailimap_ssl_connect_voip_with_callback(f, server, port, voip_enabled, + mailimap_ssl_connect_callback_ccert, f); + } +#endif + return mailimap_ssl_connect_voip_with_callback(f, server, port, voip_enabled, NULL, NULL); } @@ -127,6 +145,10 @@ static int mailimap_cfssl_connect_voip_ssl_level(mailimap * f, const char * serv if (stream == NULL) { return MAILIMAP_ERROR_CONNECTION_REFUSED; } + + if(f->client_cert_length && f->client_cert_password) + mailstream_set_client_cert(stream, f->client_cert, f->client_cert_length, f->client_cert_password); + mailstream_cfstream_set_ssl_level(stream, ssl_level); mailstream_cfstream_set_ssl_verification_mask(stream, MAILSTREAM_CFSTREAM_SSL_NO_VERIFICATION); r = mailstream_cfstream_set_ssl_enabled(stream, 1); diff --git a/src/low-level/imap/mailimap_ssl.h b/src/low-level/imap/mailimap_ssl.h index 094adb39..580289d6 100644 --- a/src/low-level/imap/mailimap_ssl.h +++ b/src/low-level/imap/mailimap_ssl.h @@ -49,7 +49,7 @@ extern "C" { LIBETPAN_EXPORT int mailimap_ssl_connect(mailimap * f, const char * server, uint16_t port); - + LIBETPAN_EXPORT int mailimap_ssl_connect_voip(mailimap * f, const char * server, uint16_t port, int voip_enabled); diff --git a/src/low-level/imap/mailimap_types.h b/src/low-level/imap/mailimap_types.h index ed6e6296..2daec88b 100644 --- a/src/low-level/imap/mailimap_types.h +++ b/src/low-level/imap/mailimap_types.h @@ -3394,6 +3394,10 @@ struct mailimap { int is_163_workaround_enabled; int is_rambler_workaround_enabled; int is_qip_workaround_enabled; + + unsigned char* client_cert; + size_t client_cert_length; + const char* client_cert_password; }; diff --git a/src/low-level/imap/mailimap_types_helper.h b/src/low-level/imap/mailimap_types_helper.h index 0e337363..79989e54 100644 --- a/src/low-level/imap/mailimap_types_helper.h +++ b/src/low-level/imap/mailimap_types_helper.h @@ -133,7 +133,7 @@ LIBETPAN_EXPORT struct mailimap_section * mailimap_section_new_header(void); /* - this function creates a mailimap_section structure to describe + this functions creates a mailimap_section structure to describe a list of headers */ @@ -142,7 +142,7 @@ struct mailimap_section * mailimap_section_new_header_fields(struct mailimap_header_list * header_list); /* - this function creates a mailimap_section structure to describe headers + this functions creates a mailimap_section structure to describe headers other than those given */ diff --git a/src/low-level/imap/quota.h b/src/low-level/imap/quota.h index e6a23c10..88a6b1d7 100644 --- a/src/low-level/imap/quota.h +++ b/src/low-level/imap/quota.h @@ -52,9 +52,6 @@ int mailimap_quota_getquotaroot(mailimap * session, const char * list_mb, struct mailimap_quota_complete_data ** result); -LIBETPAN_EXPORT -int mailimap_has_quota(mailimap * session); - #ifdef __cplusplus } #endif diff --git a/src/low-level/imap/quota_parser.c b/src/low-level/imap/quota_parser.c index 95226b0c..15fc2328 100644 --- a/src/low-level/imap/quota_parser.c +++ b/src/low-level/imap/quota_parser.c @@ -103,7 +103,7 @@ mailimap_quota_quota_resource_parse(mailstream * fd, MMAPString * buffer, struct } static int -mailimap_quota_quota_list_nonempty_parse(mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx, +mailimap_quota_quota_list_nonempty_parse(mailstream * fd, MMAPString * buffer, size_t * indx, clist ** result, size_t progr_rate, progress_function * progr_fun) { @@ -114,13 +114,13 @@ mailimap_quota_quota_list_nonempty_parse(mailstream * fd, MMAPString * buffer, s cur_token = * indx; - r = mailimap_oparenth_parse(fd, buffer, parser_ctx, &cur_token); + r = mailimap_oparenth_parse(fd, buffer, NULL, &cur_token); if (r != MAILIMAP_NO_ERROR) { res = r; goto err; } - r = mailimap_struct_spaced_list_parse(fd, buffer, parser_ctx, + r = mailimap_struct_spaced_list_parse(fd, buffer, NULL, &cur_token, "a_resource_list, &mailimap_quota_quota_resource_parse, (mailimap_struct_destructor *) @@ -131,7 +131,7 @@ mailimap_quota_quota_list_nonempty_parse(mailstream * fd, MMAPString * buffer, s goto err; } - r = mailimap_cparenth_parse(fd, buffer, parser_ctx, &cur_token); + r = mailimap_cparenth_parse(fd, buffer, NULL, &cur_token); if (r != MAILIMAP_NO_ERROR) { res = r; goto quota_list_free; @@ -151,7 +151,7 @@ mailimap_quota_quota_list_nonempty_parse(mailstream * fd, MMAPString * buffer, s } static int -mailimap_quota_quota_list_empty_parse(mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx, +mailimap_quota_quota_list_empty_parse(mailstream * fd, MMAPString * buffer, size_t * indx, clist ** result, size_t progr_rate, progress_function * progr_fun) { @@ -161,12 +161,12 @@ mailimap_quota_quota_list_empty_parse(mailstream * fd, MMAPString * buffer, stru cur_token = * indx; - r = mailimap_oparenth_parse(fd, buffer, parser_ctx, &cur_token); + r = mailimap_oparenth_parse(fd, buffer, NULL, &cur_token); if (r != MAILIMAP_NO_ERROR) { return r; } - r = mailimap_cparenth_parse(fd, buffer, parser_ctx, &cur_token); + r = mailimap_cparenth_parse(fd, buffer, NULL, &cur_token); if (r != MAILIMAP_NO_ERROR) { return r; } @@ -183,24 +183,24 @@ mailimap_quota_quota_list_empty_parse(mailstream * fd, MMAPString * buffer, stru } static int -mailimap_quota_quota_list_parse(mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx, +mailimap_quota_quota_list_parse(mailstream * fd, MMAPString * buffer, size_t * indx, clist ** result, size_t progr_rate, progress_function * progr_fun) { int r; - r = mailimap_quota_quota_list_empty_parse(fd, buffer, parser_ctx, indx, result, + r = mailimap_quota_quota_list_empty_parse(fd, buffer, indx, result, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { return r; } - return mailimap_quota_quota_list_nonempty_parse(fd, buffer, parser_ctx, indx, result, + return mailimap_quota_quota_list_nonempty_parse(fd, buffer, indx, result, progr_rate, progr_fun); } static int -mailimap_quota_quota_response_parse(mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx, +mailimap_quota_quota_response_parse(mailstream * fd, MMAPString * buffer, size_t * indx, struct mailimap_quota_quota_data ** result, size_t progr_rate, progress_function * progr_fun) { @@ -226,7 +226,7 @@ mailimap_quota_quota_response_parse(mailstream * fd, MMAPString * buffer, struct goto err; } - r = mailimap_astring_parse(fd, buffer, parser_ctx, &cur_token, "aroot, + r = mailimap_astring_parse(fd, buffer, NULL, &cur_token, "aroot, progr_rate, progr_fun); if (r != MAILIMAP_NO_ERROR) { res = r; @@ -239,7 +239,7 @@ mailimap_quota_quota_response_parse(mailstream * fd, MMAPString * buffer, struct goto quotaroot_free; } - r = mailimap_quota_quota_list_parse(fd, buffer, parser_ctx, &cur_token, + r = mailimap_quota_quota_list_parse(fd, buffer, &cur_token, "a_list, progr_rate, progr_fun); if (r != MAILIMAP_NO_ERROR) { res = r; @@ -268,7 +268,7 @@ mailimap_quota_quota_response_parse(mailstream * fd, MMAPString * buffer, struct } static int -mailimap_quota_quotaroot_response_parse(mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx, +mailimap_quota_quotaroot_response_parse(mailstream * fd, MMAPString * buffer, size_t * indx, struct mailimap_quota_quotaroot_data ** result, size_t progr_rate, progress_function * progr_fun) { @@ -295,7 +295,7 @@ mailimap_quota_quotaroot_response_parse(mailstream * fd, MMAPString * buffer, st goto err; } - r = mailimap_mailbox_parse(fd, buffer, parser_ctx, &cur_token, &mailbox, + r = mailimap_mailbox_parse(fd, buffer, NULL, &cur_token, &mailbox, progr_rate, progr_fun); if (r != MAILIMAP_NO_ERROR) { res = r; @@ -317,7 +317,7 @@ mailimap_quota_quotaroot_response_parse(mailstream * fd, MMAPString * buffer, st goto quotaroot_list_free; } - r = mailimap_astring_parse(fd, buffer, parser_ctx, &cur_token, "aroot, + r = mailimap_astring_parse(fd, buffer, NULL, &cur_token, "aroot, progr_rate, progr_fun); if (r != MAILIMAP_NO_ERROR) { res = r; @@ -386,7 +386,7 @@ int mailimap_quota_parse(int calling_parser, mailstream * fd, switch (calling_parser) { case MAILIMAP_EXTENDED_PARSER_MAILBOX_DATA: - r = mailimap_quota_quota_response_parse(fd, buffer, parser_ctx, indx, + r = mailimap_quota_quota_response_parse(fd, buffer, indx, "a_data, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { type = MAILIMAP_QUOTA_TYPE_QUOTA_DATA; @@ -394,7 +394,7 @@ int mailimap_quota_parse(int calling_parser, mailstream * fd, } if (r == MAILIMAP_ERROR_PARSE) { - r = mailimap_quota_quotaroot_response_parse(fd, buffer, parser_ctx, indx, + r = mailimap_quota_quotaroot_response_parse(fd, buffer, indx, "aroot_data, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { type = MAILIMAP_QUOTA_TYPE_QUOTAROOT_DATA; diff --git a/src/low-level/mime/mailmime_write_generic.c b/src/low-level/mime/mailmime_write_generic.c index ff44e0d5..bb63ab0a 100644 --- a/src/low-level/mime/mailmime_write_generic.c +++ b/src/low-level/mime/mailmime_write_generic.c @@ -81,9 +81,6 @@ static int mailmime_version_write_driver(int (* do_write)(void *, const char *, static int mailmime_encoding_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col, struct mailmime_mechanism * encoding); -static int mailmime_location_write_driver(int (* do_write)(void *, const char *, size_t), void *data, int *col, - char *location); - static int mailmime_language_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col, struct mailmime_language * language); @@ -172,10 +169,6 @@ static int mailmime_field_write_driver(int (* do_write)(void *, const char *, si r = mailmime_language_write_driver(do_write, data, col, field->fld_data.fld_language); break; - case MAILMIME_FIELD_LOCATION: - r = mailmime_location_write_driver(do_write, data, col, field->fld_data.fld_location); - break; - default: r = MAILIMF_ERROR_INVAL; break; @@ -317,33 +310,6 @@ static int mailmime_encoding_write_driver(int (* do_write)(void *, const char *, return MAILIMF_NO_ERROR; } -static int mailmime_location_write_driver(int (* do_write)(void *, const char *, size_t), void *data, int *col, - char *location) -{ - int r; - int len = strlen(location); - - r = mailimf_string_write_driver(do_write, data, col, "Content-Location: ", 18); - if (r != MAILIMF_NO_ERROR) - return r; - - if (*col > 1 && *col + len > MAX_MAIL_COL) { - r = mailimf_string_write_driver(do_write, data, col, "\r\n ", 3); - if (r != MAILIMF_NO_ERROR) - return r; - } - - r = mailimf_string_write_driver(do_write, data, col, location, len); - if (r != MAILIMF_NO_ERROR) - return r; - - r = mailimf_string_write_driver(do_write, data, col, "\r\n", 2); - if (r != MAILIMF_NO_ERROR) - return r; - - return MAILIMF_NO_ERROR; -} - static int mailmime_language_write_driver(int (* do_write)(void *, const char *, size_t), void * data, int * col, struct mailmime_language * language) { diff --git a/src/low-level/smtp/mailsmtp.c b/src/low-level/smtp/mailsmtp.c index 2f3b40e6..6679ecc3 100644 --- a/src/low-level/smtp/mailsmtp.c +++ b/src/low-level/smtp/mailsmtp.c @@ -113,6 +113,10 @@ mailsmtp * mailsmtp_new(size_t progr_rate, if (session == NULL) goto err; + session->client_cert_length = 0; + session->client_cert = NULL; + session->client_cert_password = NULL; + session->stream = NULL; session->progr_rate = progr_rate; @@ -164,7 +168,7 @@ void mailsmtp_free(mailsmtp * session) if (session->stream) mailsmtp_quit(session); - + mmap_string_free(session->line_buffer); mmap_string_free(session->response_buffer); free(session); @@ -231,6 +235,12 @@ int mailsmtp_quit(mailsmtp * session) int r; int res; + free(session->client_cert); + session->client_cert = NULL; + session->client_cert_length = 0; + free(session->client_cert_password); + session->client_cert_password = NULL; + if (session->stream == NULL) return MAILSMTP_NO_ERROR; @@ -1626,6 +1636,22 @@ void mailsmtp_set_logger(mailsmtp * session, void (* logger)(mailsmtp * session, session->smtp_logger_context = logger_context; } +LIBETPAN_EXPORT +void mailsmtp_set_client_cert(mailsmtp * s, unsigned char* data, size_t count, const char* password) +{ + free(s->client_cert); + s->client_cert_length = count; + s->client_cert = malloc(count); + if(s->client_cert) + memcpy(s->client_cert, data, count); + + size_t len = strlen(password); + free(s->client_cert_password); + s->client_cert_password = malloc(len + 1); + if(s->client_cert_password) + strcpy(s->client_cert_password, password); +} + int mailsmtp_send_command(mailsmtp * f, char * command) { return send_command(f, command); diff --git a/src/low-level/smtp/mailsmtp.h b/src/low-level/smtp/mailsmtp.h index c5d3a9bd..7105a62b 100644 --- a/src/low-level/smtp/mailsmtp.h +++ b/src/low-level/smtp/mailsmtp.h @@ -183,7 +183,10 @@ void mailsmtp_set_progress_callback(mailsmtp * session, LIBETPAN_EXPORT void mailsmtp_set_logger(mailsmtp * session, void (* logger)(mailsmtp * session, int log_type, const char * str, size_t size, void * context), void * logger_context); - + +LIBETPAN_EXPORT +void mailsmtp_set_client_cert(mailsmtp * session, unsigned char* data, size_t length, const char* password); + #ifdef __cplusplus } #endif diff --git a/src/low-level/smtp/mailsmtp_socket.c b/src/low-level/smtp/mailsmtp_socket.c index 69bc6464..33eda5c7 100644 --- a/src/low-level/smtp/mailsmtp_socket.c +++ b/src/low-level/smtp/mailsmtp_socket.c @@ -100,8 +100,25 @@ int mailsmtp_socket_connect(mailsmtp * session, static int mailsmtp_cfsocket_starttls(mailsmtp * session); +void mailsmtp_socket_starttls_cert(struct mailstream_ssl_context * ssl_context, void * data) +{ + mailsmtp * session = (mailsmtp*)data; + + if(ssl_context, session->client_cert && session->client_cert_length && session->client_cert_password) + { + mailstream_ssl_set_client_certicate_data(ssl_context, session->client_cert, session->client_cert_length, session->client_cert_password); + } +} + int mailsmtp_socket_starttls(mailsmtp * session) { +#if defined(ANDROID) || defined(__ANDROID__) + if(session->client_cert && session->client_cert_password) + { + return mailsmtp_socket_starttls_with_callback(session, mailsmtp_socket_starttls_cert, session); + } +#endif + return mailsmtp_socket_starttls_with_callback(session, NULL, NULL); } @@ -160,6 +177,9 @@ static int mailsmtp_cfsocket_starttls(mailsmtp * session) if (r != MAILSMTP_NO_ERROR) return r; + if(session->client_cert_length && session->client_cert_password) + mailstream_set_client_cert(session->stream, session->client_cert, session->client_cert_length, session->client_cert_password); + mailstream_cfstream_set_ssl_verification_mask(session->stream, MAILSTREAM_CFSTREAM_SSL_NO_VERIFICATION); r = mailstream_cfstream_set_ssl_enabled(session->stream, 1); if (r < 0) { diff --git a/src/low-level/smtp/mailsmtp_ssl.c b/src/low-level/smtp/mailsmtp_ssl.c index 1f3af8ba..f1518265 100644 --- a/src/low-level/smtp/mailsmtp_ssl.c +++ b/src/low-level/smtp/mailsmtp_ssl.c @@ -56,14 +56,41 @@ #define SERVICE_NAME_SMTPS "smtps" #define SERVICE_TYPE_TCP "tcp" +#if defined(ANDROID) || defined(__ANDROID__) +#include +#include "../../android_log.h" +#endif + #if HAVE_CFNETWORK static int mailsmtp_cfssl_connect(mailsmtp * session, const char * server, uint16_t port); #endif +#if defined(ANDROID) || defined(__ANDROID__) +void mailsmtp_ssl_connect_callback_ccert(struct mailstream_ssl_context * ssl_context, void * data) +{ + mailsmtp * f = (mailsmtp*)data; + + if(f->client_cert && f->client_cert_length && f->client_cert_password) + { + __android_log_print(ANDROID_LOG_INFO, "NATIVE", "setting smtp client cert"); + mailstream_ssl_set_client_certicate_data(ssl_context, f->client_cert, f->client_cert_length, f->client_cert_password); + } +} +#endif + + int mailsmtp_ssl_connect(mailsmtp * session, const char * server, uint16_t port) { + #if defined(ANDROID) || defined(__ANDROID__) + if(session->client_cert_length && session->client_cert_password) + { + __android_log_print(ANDROID_LOG_INFO, "NATIVE", "mailsmtp_ssl_connect has cc"); + return mailsmtp_ssl_connect_with_callback(session, server, port, mailsmtp_ssl_connect_callback_ccert, session); + } +#endif + return mailsmtp_ssl_connect_with_callback(session, server, port, NULL, NULL); } @@ -75,6 +102,8 @@ int mailsmtp_ssl_connect_with_callback(mailsmtp * session, int s; mailstream * stream; +__android_log_print(ANDROID_LOG_INFO, "NATIVE", "mailsmtp_ssl_connect_with_callback"); + #if HAVE_CFNETWORK if (mailstream_cfstream_enabled) { if (callback == NULL) { @@ -119,6 +148,10 @@ static int mailsmtp_cfssl_connect_ssl_level(mailsmtp * session, if (stream == NULL) { return MAILSMTP_ERROR_CONNECTION_REFUSED; } + + if(session->client_cert_length && session->client_cert_password) + mailstream_set_client_cert(stream, session->client_cert, session->client_cert_length, session->client_cert_password); + mailstream_cfstream_set_ssl_level(stream, ssl_level); mailstream_cfstream_set_ssl_verification_mask(stream, MAILSTREAM_CFSTREAM_SSL_NO_VERIFICATION); r = mailstream_cfstream_set_ssl_enabled(stream, 1); diff --git a/src/low-level/smtp/mailsmtp_types.h b/src/low-level/smtp/mailsmtp_types.h index cb457736..10ccaf70 100644 --- a/src/low-level/smtp/mailsmtp_types.h +++ b/src/low-level/smtp/mailsmtp_types.h @@ -138,6 +138,10 @@ struct mailsmtp { void (* smtp_logger)(mailsmtp * session, int log_type, const char * str, size_t size, void * context); void * smtp_logger_context; + + unsigned char* client_cert; + size_t client_cert_length; + const char* client_cert_password; }; #define MAILSMTP_DSN_NOTIFY_SUCCESS 1 diff --git a/src/main/libetpan_version.h.in b/src/main/libetpan_version.h.in index 7565737d..98a93e8e 100644 --- a/src/main/libetpan_version.h.in +++ b/src/main/libetpan_version.h.in @@ -45,19 +45,6 @@ #if @REENTRANT@ #define LIBETPAN_REENTRANT 1 #endif - -#ifndef LIBETPAN_API_CURRENT -#define LIBETPAN_API_CURRENT @API_CURRENT@ -#endif - -#ifndef LIBETPAN_API_REVISION -#define LIBETPAN_API_REVISION @API_REVISION@ -#endif - -#ifndef LIBETPAN_API_COMPATIBILITY -#define LIBETPAN_API_COMPATIBILITY @API_COMPATIBILITY@ -#endif - #endif int libetpan_get_version_major(void); diff --git a/tests/imap-sample.c b/tests/imap-sample.c index 5eade218..55370659 100644 --- a/tests/imap-sample.c +++ b/tests/imap-sample.c @@ -43,7 +43,7 @@ static char * get_msg_content(clist * fetch_result, size_t * p_msg_size) { clistiter * cur; - /* for each message (there will probably be only one message) */ + /* for each message (there will be probably only on message) */ for(cur = clist_begin(fetch_result) ; cur != NULL ; cur = clist_next(cur)) { struct mailimap_msg_att * msg_att; size_t msg_size; diff --git a/travis/before-script.sh b/travis/before-script.sh old mode 100755 new mode 100644 diff --git a/travis/script.sh b/travis/script.sh old mode 100755 new mode 100644