Browse Source

Android :

- added TrustWord DB in assets
    - added GPG external build based on gnupg-for-android external build
    - added runtime asset unpacking into file system, for native access
    - added gradle tasks and dependencies to invoke external and pEpEngine build
    - added GPGAgentService and associated android intent to start gpg-agent
    - added dumb pinentry.sh to keep gpg-agent happy

Note : temporary added import_key to basic_api for testing purpose
JNI-44
Edouard Tisserant 7 years ago
parent
commit
0d5bc01646
15 changed files with 1045 additions and 18 deletions
  1. +8
    -0
      .hgignore
  2. +46
    -6
      android/build.gradle
  3. +527
    -0
      android/external/Makefile
  4. +12
    -0
      android/external/libgcrypt-disable-hanging-random-test.patch
  5. +48
    -0
      android/external/libtool-Add-Android-Linux-support.patch
  6. +47
    -0
      android/external/pinentry.sh
  7. +3
    -6
      android/jni/Android.mk
  8. +14
    -0
      android/jni/org_pEp_jniadapter_AndroidHelper.cc
  9. BIN
      android/libs/commons-io-2.2.jar
  10. +237
    -3
      android/src/org/pEp/jniadapter/AndroidHelper.java
  11. +64
    -0
      android/src/org/pEp/jniadapter/GPGAgentService.java
  12. +22
    -0
      src/basic_api.cc
  13. +6
    -1
      src/gen_java_Engine.ysl2
  14. +10
    -2
      src/gen_java_exceptions.ysl2
  15. +1
    -0
      src/pEp.yml2

+ 8
- 0
.hgignore View File

@ -9,6 +9,8 @@ syntax: glob
*.a
*.dylib
*.so
*.orig
*~
# ignore generated files
@ -30,3 +32,9 @@ android/build
android/libs
android/obj
android/.gradle
android/external/*.git
android/assets
syntax: regexp
android/external/[^.]*

+ 46
- 6
android/build.gradle View File

@ -2,6 +2,15 @@
import org.apache.tools.ant.taskdefs.condition.Os
def pEpEngineSrc = hasProperty('pEpEngineSrc') ? pEpEngineSrc : "../../pEpEngine"
def buildAutomatic = hasProperty('buildAutomatic') ? buildAutomatic : "true"
def pEpEngineAndroid = new File(new File(pEpEngineSrc), 'build-android')
def libetpanAndroid = new File(new File(pEpEngineSrc), '../libetpan/build-android')
def externalInstallDir = file('external/data/data/' + pEpAppPackageName + '/app_opt')
def externalIncludePath = new File(externalInstallDir, 'include').absolutePath
buildscript {
repositories {
jcenter()
@ -35,10 +44,14 @@ android {
// disable automatic ndk-build call, which ignore our Android.mk
jni.srcDirs = []
jniLibs.srcDir 'libs'
assets.srcDirs = ['assets']
}
}
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}
lintOptions {
abortOnError false
}
@ -56,21 +69,48 @@ android {
commandLine 'make', 'gensource'
}
// call external build (GnuPG, GPGME, etc)
task buildExternal(type:Exec) {
workingDir 'external'
commandLine 'make', 'all', 'PEP_PACKAGE_NAME='+pEpAppPackageName
}
// call pEpEngine Build
task buildpEpEngine(type:Exec) {
workingDir pEpEngineAndroid
environment['GPGME_INCLUDE_PATH'] = externalIncludePath
commandLine './build.sh'
}
if(buildAutomatic=="true"){
buildpEpEngine.dependsOn buildExternal
}
// unzip some of the dependencies
task unzipDeps(type: Copy) {
from zipTree(file('../../pEpEngine/build-android/pEpEngine-android-1.zip'))
from zipTree(file('../../libetpan/build-android/libetpan-android-1.zip'))
from zipTree(file('../../libetpan/build-android/dependencies/openssl/openssl-android-1.zip'))
from zipTree(file('../../libetpan/build-android/dependencies/cyrus-sasl/cyrus-sasl-android-1.zip'))
from zipTree(new File(pEpEngineAndroid, 'pEpEngine-android-1.zip'))
from zipTree(new File(libetpanAndroid, 'libetpan-android-1.zip'))
from zipTree(new File(libetpanAndroid, 'dependencies/openssl/openssl-android-1.zip'))
from zipTree(new File(libetpanAndroid, 'dependencies/cyrus-sasl/cyrus-sasl-android-1.zip'))
into file("${buildDir}")
}
if(buildAutomatic=="true"){
unzipDeps.dependsOn buildpEpEngine
}
// copy pEpEnginge's system.db to asset
task cpDBAssets(type: Copy) {
from file(new File(new File(pEpEngineSrc), 'db/system.db'))
into 'assets'
}
// call regular ndk-build(.cmd) script from app directory
task jniBuild(type: Exec) {
commandLine getNdkBuildCmd(), 'V=1'
commandLine getNdkBuildCmd(), 'V=1', 'GPGBUILD='+externalInstallDir.absolutePath
}
jniBuild.dependsOn genSources
jniBuild.dependsOn unzipDeps
jniBuild.dependsOn cpDBAssets
// Ensure this is done before java build
tasks.withType(JavaCompile) {


+ 527
- 0
android/external/Makefile View File

@ -0,0 +1,527 @@
#------------------------------------------------------------------------------#
# Makefile to build GPGME, GnuPG and deps for use with pEpEngine
# based on gnupg-for-android/external/Makefile
#------------------------------------------------------------------------------#
#------------------------------------------------------------------------------#
# Build parameters
# TODO: get params from the outside for multiarch build
NDK_ABI ?= arm
NDK_TOOLCHAIN_VERSION ?= 4.8
APP_ABI ?= armeabi-v7a
APP_PLATFORM ?= android-14
PEP_PACKAGE_NAME ?= com.pep.pepjniaaractivity
#------------------------------------------------------------------------------#
# Clone update and archive external projects GIT repos
# Local clone is in external/$project.git while
# slected commit is archived in external/$project
EXTERNAL_GIT_REPOS = \
gnupg|git://git.gnupg.org/gnupg.git?08c00cd\
libassuan|git://git.gnupg.org/libassuan.git?261498d\
libgcrypt|git://git.gnupg.org/libgcrypt.git?b3936b6\
libgpg-error|git://git.gnupg.org/libgpg-error.git?bcd9295\
libksba|git://git.gnupg.org/libksba.git?02079b5\
curl|https://github.com/bagder/curl?f77e89c\
npth|git://git.gnupg.org/npth.git?79fbdce\
gpgme|git://git.gnupg.org/gpgme.git?37d927a
define per_repo_targets
$(1).git:
git clone $(2) $(1).git
$(1).git_update: $(1).git
cd $(1).git; git pull
$(1): |$(1).git
mkdir $(1)
(cd $(1).git; git archive --format=tar $(3)) | tar -C $(1) -x
$(1)_clean:
rm -rf $(1)
EXTERNAL_LOCAL_GITS += $(1).git
EXTERNAL_LOCAL_GITS_UPDATE += $(1).git_update
EXTERNAL_SRCS += $(1)
EXTERNAL_SRCS_CLEAN += $(1)_clean
endef
define per_repo
$(call per_repo_targets,\
$(1),\
$(word 1,$(subst ?, ,$(2))),\
$(word 2,$(subst ?, ,$(2))))
endef
$(foreach repo, $(EXTERNAL_GIT_REPOS), $(eval $(call per_repo,\
$(word 1,$(subst |, ,$(repo))),\
$(word 2,$(subst |, ,$(repo))))))
git_update: $(EXTERNAL_LOCAL_GITS_UPDATE)
#------------------------------------------------------------------------------#
# Manage paths for PREFIX, DESTDIR, LOCAL and PATH
EXTERNAL_ROOT := $(shell pwd)
# install root for built files
DESTDIR = $(EXTERNAL_ROOT)
prefix = /data/data/$(PEP_PACKAGE_NAME)/app_opt
LOCAL := $(DESTDIR)$(prefix)
PATH := ${PATH}:$(NDK_TOOLCHAIN)/bin:$(LOCAL)/bin
#------------------------------------------------------------------------------#
# NDK toolchain integration
# TODO: cleanup.
# Android now has 64-bit and 32-bit versions of the NDK for GNU/Linux. We
# assume that the build platform uses the appropriate version, otherwise the
# user building this will have to manually set NDK_PROCESSOR or NDK_TOOLCHAIN.
CPU := $(shell uname -m)
ifeq ($(CPU),x86_64)
NDK_PROCESSOR=x86_64
else
NDK_PROCESSOR=x86
endif
NDK_SYSROOT=$(ANDROID_NDK_HOME)/platforms/$(APP_PLATFORM)/arch-$(NDK_ABI)
NDK_UNAME := $(shell uname -s | tr '[A-Z]' '[a-z]')
ifeq ($(NDK_ABI),x86)
HOST = i686-linux-android
NDK_TOOLCHAIN = $(NDK_ABI)-$(NDK_TOOLCHAIN_VERSION)
else
HOST = $(NDK_ABI)-linux-androideabi
NDK_TOOLCHAIN = $(HOST)-$(NDK_TOOLCHAIN_VERSION)
endif
NDK_TOOLCHAIN_BASE=$(ANDROID_NDK_HOME)/toolchains/$(NDK_TOOLCHAIN)/prebuilt/$(NDK_UNAME)-$(NDK_PROCESSOR)
# include Android's build flags
TARGET_ARCH_ABI = $(APP_ABI)
include $(ANDROID_NDK_HOME)/toolchains/$(NDK_TOOLCHAIN)/setup.mk
CC := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-gcc --sysroot=$(NDK_SYSROOT)
CXX := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-g++
CPP := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-cpp
LD := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-ld
AR := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-ar
RANLIB := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-ranlib
STRIP := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)-strip \
--strip-unneeded -R .note -R .comment
CFLAGS = -DANDROID -I$(LOCAL)/include $(TARGET_CFLAGS)
LDFLAGS = -llog -L$(LOCAL)/lib $(TARGET_LDFLAGS)
# change 'release' to 'debug' for unoptimized debug builds
ifeq ($(APP_ABI),armeabi-v7a)
CFLAGS += $(TARGET_arm_release_CFLAGS)
endif
ifeq ($(APP_ABI),armeabi)
CFLAGS += $(TARGET_thumb_release_CFLAGS)
endif
#------------------------------------------------------------------------------#
# GNU Tools trickery
# point pkg-config to the .pc files generated from these builds
export PKG_CONFIG_PATH=$(LOCAL)/lib/pkgconfig
# workaround for cross-compiling bug in autoconf
export ac_cv_func_malloc_0_nonnull=yes
# GnuPG does not work with automake 1.14, it has proven reliable on 1.11, and
# that's widely available, so we'll add it to the env here, and the
# ./autogen.sh scripts will pick it up.
# http://lists.gnupg.org/pipermail/gnupg-devel/2013-August/027857.html
export AUTOMAKE=automake-1.11
.PHONY = clean distclean install-clean \
libgpg-error-build libgpg-error-clean libgpg-error-install \
libgcrypt-build libgcrypt-clean libgcrypt-install \
libassuan-build libassuan-clean libassuan-install \
libksba-build libksba-clean libksba-install \
gnupg-build gnupg-clean \
curl-build curl-clean curl-install \
npth-build npth-clean npth-install \
assets clean-assets \
$(EXTERNAL_LOCAL_GITS_UPDATE) $(EXTERNAL_SRCS_CLEAN) \
showsetup
all: gnupg-install gpgme-install assets
#------------------------------------------------------------------------------#
# debugging stuff
showsetup:
@echo "NDK_TOOLCHAIN_VERSION: $(NDK_TOOLCHAIN_VERSION)"
@echo "NDK_TOOLCHAIN: $(NDK_TOOLCHAIN)"
@echo "NDK_SYSROOT: $(NDK_SYSROOT)"
@echo "APP_PLATFORM: $(APP_PLATFORM)"
@echo "APP_ABI: $(APP_ABI)"
@echo "HOST: $(HOST)"
@echo "CC: $(CC)"
@echo "LD: $(LD)"
@echo "CFLAGS: $(CFLAGS)"
@echo "LDFLAGS: $(LDFLAGS)"
#------------------------------------------------------------------------------#
# libgpg-error
libgpg-error/configure: libgpg-error libgpg-error/configure.ac
cd libgpg-error && ./autogen.sh
libgpg-error/Makefile: libgpg-error/configure
cd libgpg-error && \
./configure \
CC="$(CC)" \
AR=$(AR) \
RANLIB=$(RANLIB) \
CFLAGS="$(CFLAGS)" \
LDFLAGS="$(LDFLAGS)" \
--disable-doc \
--disable-languages \
--host=$(HOST) \
--prefix=$(LOCAL)
ls -l libgpg-error/libtool
# brute force and ignorance to make libtool comply with android style
sed -i 's,^fast_install=.*,fast_install=needless,' libgpg-error/libtool
sed -i 's,^version_type=.*,version_type=none,' libgpg-error/libtool
sed -i 's,^shlibpath_overrides_runpath=.*,shlibpath_overrides_runpath=yes,' libgpg-error/libtool
sed -i 's,^library_names_spec=.*,library_names_spec="\\$$libname\\$$release\\$$shared_ext",' libgpg-error/libtool
sed -i 's,^soname_spec=.*,soname_spec="\\$$libname\\$$release\\$$shared_ext",' libgpg-error/libtool
sed -i 's,^finish_cmds=.*,finish_cmds="",' libgpg-error/libtool
sed -i 's,^sys_lib_dlsearch_path_spec=.*,sys_lib_dlsearch_path_spec="/lib /usr/lib",' libgpg-error/libtool
libgpg-error/src/.libs/libgpg-error.so: libgpg-error/Makefile
$(MAKE) -C libgpg-error
libgpg-error-build: libgpg-error/src/.libs/libgpg-error.so
$(LOCAL)/lib/libgpg-error.so: libgpg-error/src/.libs/libgpg-error.so
$(MAKE) -C libgpg-error prefix=$(LOCAL) install
ls -l $(LOCAL)/lib/libgpg-error.so*
libgpg-error-install: $(LOCAL)/lib/libgpg-error.so
libgpg-error-clean:
-$(MAKE) -C libgpg-error clean
rm -rf libgpg-error/configure libgpg-error/Makefile
#------------------------------------------------------------------------------#
# libgcrypt
libgcrypt/configure: libgcrypt libgcrypt/configure.ac
cd libgcrypt && ./autogen.sh
libgcrypt/Makefile: libgcrypt/configure
cd libgcrypt && \
CC="$(CC)" AR="$(AR)" RANLIB=$(RANLIB) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
./configure \
--enable-maintainer-mode \
--host=$(HOST) \
--with-gpg-error-prefix=$(LOCAL) \
--prefix=$(LOCAL)
-patch -N -p1 --reject-file=- libgcrypt/tests/random.c libgcrypt-disable-hanging-random-test.patch
libgcrypt/src/.libs/libgcrypt.so: $(LOCAL)/lib/libgpg-error.so libgcrypt/Makefile
$(MAKE) -C libgcrypt
$(LOCAL)/lib/libgcrypt.so: libgcrypt/src/.libs/libgcrypt.so
$(MAKE) -C libgcrypt prefix=$(LOCAL) install
ls -l $(LOCAL)/lib/libgcrypt.so
libgcrypt-build: libgcrypt/src/.libs/libgcrypt.so
libgcrypt-install: $(LOCAL)/lib/libgcrypt.so
libgcrypt-clean:
-$(MAKE) -C libgcrypt clean
rm -rf libgcrypt/configure libgcrypt/Makefile
#------------------------------------------------------------------------------#
# libassuan
libassuan/configure: libassuan libassuan/configure.ac
cd libassuan && ./autogen.sh && autoreconf --install --force --verbose
libassuan/Makefile: libassuan/configure
-patch -N -p1 --reject-file=- libassuan/m4/libtool.m4 libtool-Add-Android-Linux-support.patch
cd libassuan && \
CC="$(CC)" AR="$(AR)" RANLIB=$(RANLIB) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
./configure \
--enable-maintainer-mode \
--host=$(HOST) \
--with-gpg-error-prefix=$(LOCAL) \
--prefix=$(LOCAL)
libassuan/src/.libs/libassuan.so: $(LOCAL)/lib/libgpg-error.so libassuan/Makefile
$(MAKE) -C libassuan
$(LOCAL)/lib/libassuan.so: libassuan/src/.libs/libassuan.so
$(MAKE) -C libassuan prefix=$(LOCAL) install
ls -l $(LOCAL)/lib/libassuan.so
libassuan-build: libassuan/src/.libs/libassuan.so
libassuan-install: $(LOCAL)/lib/libassuan.so
libassuan-clean:
-$(MAKE) -C libassuan clean
rm -rf libassuan/configure libassuan/Makefile
#------------------------------------------------------------------------------#
# npth
npth/configure: npth npth/configure.ac
cd npth && ./autogen.sh && autoreconf --install --force --verbose
npth/Makefile: npth/configure
-patch -N -p1 --reject-file=- npth/m4/libtool.m4 libtool-Add-Android-Linux-support.patch
cd npth && \
CC="$(CC)" AR="$(AR)" RANLIB=$(RANLIB) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
./configure \
--enable-maintainer-mode \
--host=$(HOST) \
--with-gnu-ld \
--prefix=$(LOCAL)
npth/src/.libs/libnpth.so: $(LOCAL)/lib/libgpg-error.so npth/Makefile
$(MAKE) -C npth
$(LOCAL)/lib/libnpth.so: npth/src/.libs/libnpth.so
$(MAKE) -C npth prefix=$(LOCAL) install
ls -l $(LOCAL)/lib/libnpth.so*
npth-build: npth/src/.libs/libnpth.so
npth-install: $(LOCAL)/lib/libnpth.so
npth-clean:
-$(MAKE) -C npth clean
rm -rf npth/Makefile npth/configure
#------------------------------------------------------------------------------#
# libksba
libksba/configure: libksba libksba/configure.ac
cd libksba && ./autogen.sh
libksba/Makefile: $(LOCAL)/lib/libgpg-error.so libksba/configure
-patch -N -p1 --reject-file=- libksba/m4/libtool.m4 libtool-Add-Android-Linux-support.patch
cd libksba && \
CC="$(CC)" AR="$(AR)" RANLIB=$(RANLIB) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
./configure \
--enable-maintainer-mode \
--host=$(HOST) \
--with-gpg-error-prefix=$(LOCAL) \
--prefix=$(LOCAL)
libksba/src/.libs/libksba.so: libksba/Makefile
$(MAKE) -C libksba
$(LOCAL)/lib/libksba.so: libksba/src/.libs/libksba.so
$(MAKE) -C libksba prefix=$(LOCAL) install
ls -l $(LOCAL)/lib/libksba.so
libksba-build: libksba/src/.libs/libksba.so
libksba-install: $(LOCAL)/lib/libksba.so
libksba-clean:
-$(MAKE) -C libksba clean
rm -rf libksba/configure libksba/Makefile
#------------------------------------------------------------------------------#
# curl
curl/configure: curl curl/configure.ac
cd curl && ./buildconf
curl/Makefile: curl/configure
-patch -N -p1 --reject-file=- curl/m4/libtool.m4 libtool-Add-Android-Linux-support.patch
cd curl && \
CC="$(CC)" AR="$(AR)" RANLIB=$(RANLIB) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
./configure \
--host=$(HOST) \
--prefix=$(prefix) \
--with-gnu-ld \
--disable-imap \
--disable-ldap \
--disable-pop3 \
--disable-rtsp \
--disable-smtp
# brute force and ignorance to make libtool comply with android style
sed -i 's,^fast_install=.*,fast_install=needless,' curl/libtool
sed -i 's,^version_type=.*,version_type=none,' curl/libtool
sed -i 's,^shlibpath_overrides_runpath=.*,shlibpath_overrides_runpath=yes,' curl/libtool
sed -i 's,^library_names_spec=.*,library_names_spec="\\$$libname\\$$release\\$$shared_ext",' curl/libtool
sed -i 's,^soname_spec=.*,soname_spec="\\$$libname\\$$release\\$$shared_ext",' curl/libtool
sed -i 's,^finish_cmds=.*,finish_cmds="",' curl/libtool
sed -i 's,^sys_lib_dlsearch_path_spec=.*,sys_lib_dlsearch_path_spec="/lib /usr/lib",' curl/libtool
curl/lib/.libs/libcurl.so: curl/Makefile
$(MAKE) -C curl
$(LOCAL)/lib/libcurl.so: curl/lib/.libs/libcurl.so
$(MAKE) -C curl DESTDIR=$(DESTDIR) prefix=$(prefix) install
ls -l $(LOCAL)/lib/libcurl.so
curl-build: curl/lib/.libs/libcurl.so
curl-install: $(LOCAL)/lib/libcurl.so
curl-clean:
-$(MAKE) -C curl clean
rm -f curl/Makefile
#------------------------------------------------------------------------------#
# gnupg
gnupg/configure: gnupg
cd gnupg && ./autogen.sh
gnupg/Makefile: gnupg/configure
cd gnupg && \
CC="$(CC)" AR="$(AR)" RANLIB=$(RANLIB) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
./configure \
--enable-maintainer-mode \
--host=$(HOST) \
--with-gpg-error-prefix=$(LOCAL) \
--with-libgcrypt-prefix=$(LOCAL) \
--with-libassuan-prefix=$(LOCAL) \
--with-ksba-prefix=$(LOCAL) \
--with-npth-prefix=$(LOCAL) \
--with-libcurl=$(LOCAL) \
--disable-ldap \
--without-libiconv-prefix \
--disable-doc \
--disable-g13 \
--disable-ntbtls \
--disable-gnutls \
--enable-dirmngr-auto-start \
--with-agent-pgm=$(prefix)/bin/gpg-agent \
--with-pinentry-pgm=$(prefix)/bin/pinentry.sh \
--with-dirmngr-pgm=$(prefix)/bin/dirmngr \
--with-protect-tool-pgm=$(prefix)/libexec/gpg-protect-tool \
--with-scdaemon-pgm=$(prefix)/bin/scdaemon \
--prefix=$(prefix)
gnupg/g10/gpg2: $(LOCAL)/lib/libgpg-error.so $(LOCAL)/lib/libgcrypt.so $(LOCAL)/lib/libksba.so $(LOCAL)/lib/libassuan.so $(LOCAL)/lib/libnpth.so $(LOCAL)/lib/libcurl.so gnupg/Makefile
$(MAKE) -C gnupg
$(LOCAL)/bin/gpg2: gnupg/g10/gpg2 gnupg/configure
$(MAKE) -C gnupg prefix=$(LOCAL) install
ls -l $(LOCAL)/bin/gpg2
$(LOCAL)/bin/pinentry.sh: pinentry.sh
install $< $(LOCAL)/bin
gnupg-build: gnupg/g10/gpg2
gnupg-install: $(LOCAL)/bin/gpg2 $(LOCAL)/bin/pinentry.sh
install -d $(LOCAL)/etc/gnupg
install -d $(LOCAL)/var/run/gnupg
install -d $(LOCAL)/var/cache/gnupg
gnupg-clean:
-$(MAKE) -C gnupg
#------------------------------------------------------------------------------#
# gpgme
gpgme/configure: gpgme gpgme/configure.ac
cd gpgme && ./autogen.sh
gpgme/Makefile: gpgme/configure
-patch -N -p1 --reject-file=- gpgme/m4/libtool.m4 libtool-Add-Android-Linux-support.patch
cd gpgme && \
CC="$(CC)" AR="$(AR)" RANLIB=$(RANLIB) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
./configure \
--host=$(HOST) \
--enable-maintainer-mode \
--with-gpg-error-prefix=$(LOCAL) \
--with-libassuan-prefix=$(LOCAL) \
--enable-fixed-path=$(prefix)/bin \
--without-g13 \
--disable-glibtest \
--disable-gpg-test \
--disable-gpgsm-test \
--disable-gpgconf-test \
--disable-g13-test \
--prefix=$(prefix)
gpgme/src/.libs/libgpgme.so: gpgme/Makefile
$(MAKE) -C gpgme
$(LOCAL)/lib/libgpgme.so: gpgme/src/.libs/libgpgme.so
$(MAKE) -C gpgme DESTDIR=$(DESTDIR) prefix=$(prefix) install
gpgme-build: gpgme/src/.libs/libgpgme.so
gpgme-install: $(LOCAL)/bin/gpg2 $(LOCAL)/lib/libgpgme.so
gpgme-clean:
-$(MAKE) -C gpgme clean
-rm -f gpgme/Makefile gpgme/configure
#------------------------------------------------------------------------------#
# assets for Android app
clean-assets:
rm -rf $(ASSETS)
ASSETS := $(EXTERNAL_ROOT)/../assets
assets: clean-assets
# add the new stuff
install -d $(ASSETS)
cp -a $(LOCAL)/* $(ASSETS)
# remove all the stuff we don't need
rm -f $(ASSETS)/bin/*-static
rm -f $(ASSETS)/bin/curl*
rm -f $(ASSETS)/lib/*.a $(ASSETS)/lib/*.la
# remove lib symlinks since Android AssetManager copies them as files
rm -f $(ASSETS)/lib/*.so
# remove .so.0 symlink and rename the .so.0.12.0 file to it
for f in $(ASSETS)/lib/*.so.[0-9]*; do \
echo $$f; \
test ! -L $$f || \
(rm $$f && mv $$f.[0-9]* $$f); \
done
rm -rf $(ASSETS)/include
rm -rf $(ASSETS)/share/man $(ASSETS)/share/info $(ASSETS)/share/doc
rm -rf $(ASSETS)/tests
#------------------------------------------------------------------------------#
# clean
install-clean:
rm -rf -- $(LOCAL)
clean: install-clean gnupg-clean curl-clean libksba-clean libassuan-clean npth-clean libgcrypt-clean libgpg-error-clean
distclean: clean install-clean
-$(MAKE) -C gnupg distclean
-$(MAKE) -C curl distclean
-rm -f curl/configure # their distclean fails to rm this
-$(MAKE) -C libksba distclean
-$(MAKE) -C npth distclean
-$(MAKE) -C libassuan distclean
-$(MAKE) -C libgcrypt distclean
-$(MAKE) -C libgpg-error distclean
gitclean: $(EXTERNAL_SRCS_CLEAN)
rm -rf $(ASSETS)
rm -rf $(EXTERNAL_ROOT)/data

+ 12
- 0
android/external/libgcrypt-disable-hanging-random-test.patch View File

@ -0,0 +1,12 @@
diff --git a/libgcrypt/tests/random.c b/libgcrypt/tests/random.c
index 10bf646..a52aacc 100644
--- a/libgcrypt/tests/random.c
+++ b/libgcrypt/tests/random.c
@@ -439,7 +439,6 @@ run_all_rng_tests (const char *program)
"--early-rng-check --prefer-fips-rng",
"--early-rng-check --prefer-system-rng",
"--prefer-standard-rng",
- "--prefer-fips-rng",
"--prefer-system-rng",
NULL
};

+ 48
- 0
android/external/libtool-Add-Android-Linux-support.patch View File

@ -0,0 +1,48 @@
commit 8eeeb00daef8c4f720c9b79a0cdb89225d9909b6
Author: David 'Digit' Turner <digit@google.com>
Date: Tue Oct 8 14:37:32 2013 -0700
libtool: Add Android/Linux support.
This patch adds proper Android support to libtool. The main
issues are the following:
- Versioned libraries are not supported by the platform and
its build/packaging tools.
- The dynamic linker is not GNU ld, there is no support for
DT_RUNPATH.
- Similarly, there is no ldconfig.
diff --git a/m4/libtool.m4 b/m4/libtool.m4
index 80d7e44..080272c 100644
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
@@ -2683,6 +2683,26 @@ linux*oldld* | linux*aout* | linux*coff*)
dynamic_linker=no
;;
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ ;;
+
# This must be glibc/ELF.
linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
version_type=linux # correct to gnu/linux during the next big refactor

+ 47
- 0
android/external/pinentry.sh View File

@ -0,0 +1,47 @@
#!/system/bin/sh
echo OK
while read cmd rest
do
case $cmd in
SETDESC)
DESC=$rest
echo OK
;;
SETPROMPT)
PROMPT=$rest
echo OK
;;
SETOK)
OK=$rest
echo OK
;;
SETERROR)
ERROR=$rest
echo OK
;;
GETPIN)
echo "D "
echo OK
;;
OPTION)
echo OK
;;
GETINFO)
case $rest in
pid*)
echo D $$
echo OK
;;
esac
;;
BYE)
echo OK
exit
;;
*)
echo OK
;;
esac
done

+ 3
- 6
android/jni/Android.mk View File

@ -1,10 +1,5 @@
LOCAL_PATH:= $(call my-dir)
GPGEXT := ../../../gnupg-for-android/external
GPGROOT := data/data/info.guardianproject.gpg/app_opt
GPGBUILD := $(GPGEXT)/$(GPGROOT)
include $(CLEAR_VARS)
LOCAL_MODULE := libassuan
LOCAL_SRC_FILES := $(GPGBUILD)/lib/libassuan.so
@ -28,7 +23,7 @@ include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libgpgme
LOCAL_SRC_FILES := $(GPGBUILD)/lib/libgpgme.so
LOCAL_EXPORT_C_INCLUDES := $(GPGEXT)/$(GPGROOT)/include $(GPGEXT)/gpgme/src
LOCAL_EXPORT_C_INCLUDES := $(GPGBUILD)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
@ -78,11 +73,13 @@ LOCAL_SRC_FILES := \
../../src/org_pEp_jniadapter_Engine.cc \
../../src/org_pEp_jniadapter_Message.cc \
../../src/throw_pEp_exception.cc \
../../src/basic_api.cc \
../../src/jniutils.cc
LOCAL_C_INCLUDES := ../../src
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := pEpJNIAndroidHelper
LOCAL_SHARED_LIBRARIES := libgpgme
LOCAL_SRC_FILES := org_pEp_jniadapter_AndroidHelper.cc
include $(BUILD_SHARED_LIBRARY)

+ 14
- 0
android/jni/org_pEp_jniadapter_AndroidHelper.cc View File

@ -3,6 +3,8 @@
#include <stdlib.h>
#include <gpgme.h>
extern "C" {
JNIEXPORT jint JNICALL Java_org_pEp_jniadapter_AndroidHelper_setenv
@ -16,5 +18,17 @@ JNIEXPORT jint JNICALL Java_org_pEp_jniadapter_AndroidHelper_setenv
return err;
}
JNIEXPORT jint JNICALL Java_org_pEp_jniadapter_AndroidHelper_nativeSetup
(JNIEnv* env, jclass clazz, jstring debugflag)
{
char* cdebugflag = (char *) env->GetStringUTFChars(debugflag, NULL);
gpgme_set_global_flag("debug", cdebugflag);
env->ReleaseStringUTFChars(debugflag, cdebugflag);
gpgme_set_global_flag ("disable-gpgconf", "");
gpgme_set_global_flag ("gpg-name", "gpg2");
return 0;
}
} // extern "C"

BIN
android/libs/commons-io-2.2.jar View File


+ 237
- 3
android/src/org/pEp/jniadapter/AndroidHelper.java View File

@ -1,17 +1,251 @@
package org.pEp.jniadapter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Scanner;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
import android.content.Intent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class AndroidHelper {
static {
System.loadLibrary("pEpJNIAndroidHelper");
}
public static final String TAG = "AndroidHelper";
private static native int setenv(String key, String value, boolean overwrite);
private static native int nativeSetup(String debugflag);
private static File homeDir;
private static File optDir;
private static File versionFile;
public static File binDir;
// TODO : Increment when needed.
public static int VERSION_CODE = 0;
private static File shareDir;
private static final String dBFileName = "system.db";
private static File dBfile;
private static boolean already = false;
public static void startDaemonIfNeeded(Context c) {
if (!new File(homeDir, "S.gpg-agent").exists()) {
Intent service = new Intent(c, GPGAgentService.class);
c.startService(service);
}
}
public static void envSetup(Context c) {
// "/opt" like dir to unpack GnuPG assets
optDir = c.getDir("opt", Context.MODE_PRIVATE);
// Add GnuPG's bin to PATH
binDir = new File(optDir, "bin");
setenv("PATH", System.getenv("PATH") + ":" +
binDir.getAbsolutePath(), true);
// Tell dynamic loader where to find libs
String appLibDir = "";
try {
appLibDir = new File(c.getApplicationInfo().nativeLibraryDir).getCanonicalPath();
} catch (Exception e) {
e.printStackTrace();
appLibDir = new File(c.getApplicationInfo().nativeLibraryDir).getAbsolutePath();
}
File libDir = new File(optDir, "lib");
setenv("LD_LIBRARY_PATH", appLibDir + ":" +
libDir.getAbsolutePath() + ":" +
System.getenv("LD_LIBRARY_PATH"), true);
// Set HOME environment variable pointing to
// something like "/data/data/app.package.name/home"
// pEpEngine use it to find management DB and gpg home
homeDir = c.getDir("home", Context.MODE_PRIVATE);
setenv("HOME", homeDir.getAbsolutePath(), true);
// pEpEngine need to find the safe words database
shareDir = c.getDir("trustwords", Context.MODE_PRIVATE);
dBfile = new File(shareDir, dBFileName);
// TRUSTWORDS is absolute path of dir containig system.db
setenv("TRUSTWORDS", shareDir.getAbsolutePath(), true);
// Check version file retains latest installed version
versionFile = new File(c.getFilesDir(), "VERSION");
}
public static void assetsSetup(Context c) {
envSetup(c);
boolean needUpgrade = needNewAssets();
// If system.db still not here, then go get it in the assets.
if (dBfile.exists() && needUpgrade){
dBfile.delete();
}
if (!dBfile.exists()){
assetFileExtract(c, dBFileName, shareDir);
}
// Copy GnuPG binaries
if (optDir.exists() && needUpgrade){
try {
FileUtils.deleteDirectory(optDir);
} catch (IOException e) {
Log.e(TAG, "Couldn't delete existing gpg binaries");
}
}
if (!optDir.exists()){
optDir.mkdirs();
assetPathExtract(c, "lib", optDir);
assetPathExtract(c, "bin", optDir);
new File(optDir, "var/cache/gnupg").mkdirs();
new File(optDir, "var/lib/gnupg").mkdirs();
new File(optDir, "var/run/gnupg").mkdirs();
chmod("0755", optDir, true);
}
// Fill version file
setInstalledVersion(c);
}
public static void nativeSetup(Context c) {
// pre-load libs for pepengine, as
// android cannot solve lib dependencies on its own
System.loadLibrary("gpg-error");
System.loadLibrary("assuan");
System.loadLibrary("gpgme");
// Launch native side setup
// TODO disable debug when done
nativeSetup( "9:"+new File(c.getFilesDir(), "gpgme.log").getAbsolutePath());
}
public static void setup(Context c) {
setenv("HOME",
c.getDir("home", Context.MODE_PRIVATE).getAbsolutePath(),
true);
if(!already){
already = true;
assetsSetup(c);
nativeSetup(c);
startDaemonIfNeeded(c);
}
}
private static void assetPathExtract(Context c, String assetPath, File targetDir) {
AssetManager assetManager = c.getAssets();
try {
String items[] = assetManager.list(assetPath);
if (items.length > 0) {
File newDir = new File(targetDir, new File(assetPath).getName());
if (!newDir.exists())
newDir.mkdirs();
for (int i = 0; i < items.length; ++i) {
assetPathExtract(c, new File(assetPath, items[i]).getPath(), newDir);
}
} else {
assetFileExtract(c, assetPath, targetDir);
}
} catch (IOException ex) {
Log.e(TAG, assetPath + " : ", ex);
}
}
private static void assetFileExtract(Context c, String assetPath, File targetDir) {
AssetManager assetManager = c.getAssets();
try {
InputStream inputStream = assetManager.open(assetPath);
String targetFileName =
new File(targetDir,
new File(assetPath).getName()).getAbsolutePath();
OutputStream outputStream = new FileOutputStream(targetFileName);
IOUtils.copy(inputStream, outputStream);
outputStream.close();
inputStream.close();
Log.i(TAG, "asset " + assetPath + " extracted as " + targetFileName);
} catch (Exception e) {
Log.e(TAG, assetPath + ": " + e.getMessage());
}
}
private static int getInstalledVersion() {
int versionCode = -1;
if (versionFile.exists()){
try {
Scanner scan = new Scanner(versionFile);
versionCode = Integer.parseInt(scan.next());
scan.close();
} catch (Exception e) {
Log.e(TAG, "getInstalledVersion: " + e.getMessage());
}
}
return versionCode;
}
private static void setInstalledVersion(Context context) {
try {
FileOutputStream fileOutputStream = new FileOutputStream(versionFile);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
outputStreamWriter.write(String.valueOf(VERSION_CODE) + "\n");
outputStreamWriter.close();
fileOutputStream.close();
} catch (Exception e) {
Log.e(TAG, "setInstalledVersion: " + e.getMessage());
}
}
public static boolean needNewAssets() {
return VERSION_CODE != getInstalledVersion();
}
// TODO: replace with native impl, less prone to failure.
public static void chmod(String modestr, File path) {
int err = 1;
try {
Class<?> fileUtils = Class.forName("android.os.FileUtils");
Method setPermissions = fileUtils.getMethod("setPermissions",
String.class, int.class, int.class, int.class);
err = (Integer) setPermissions.invoke(
null, path.getAbsolutePath(),
Integer.parseInt(modestr, 8),
-1, -1);
if (err != 0) {
Log.i(TAG, "android.os.FileUtils.setPermissions() returned " + err
+ " for '" + path + "'");
}
} catch (Exception e) {
Log.i(TAG, "chmod:", e);
}
}
public static void chmod(String mode, File path, boolean recursive) {
chmod(mode, path);
if (recursive) {
File[] paths = path.listFiles();
for (File pth : paths) {
if (pth.isDirectory()) {
chmod(mode, pth, true);
} else {
chmod(mode, pth);
}
}
}
}
}

+ 64
- 0
android/src/org/pEp/jniadapter/GPGAgentService.java View File

@ -0,0 +1,64 @@
package org.pEp.jniadapter;
import java.io.File;
import android.content.Intent;
import android.app.Service;
import android.util.Log;
import android.os.IBinder;
public class GPGAgentService extends Service {
public static final String TAG = "GPGAgentService";
private AgentProcessThread process;
class AgentProcessThread extends Thread {
@Override
public void run() {
Log.i(TAG, "execute GPG agent");
try {
Runtime.getRuntime().exec(
"gpg-agent" +
" --pinentry-program " +
new File(AndroidHelper.binDir, "pinentry.sh").getAbsolutePath() +
" --no-detach" +
" --daemon --write-env-file" +
" --batch" +
" --debug-level basic --log-file "
+ new File(GPGAgentService.this.getFilesDir(), "gpg-agent.log")).waitFor();
Log.i(TAG, "execution terminated");
} catch (Exception e) {
Log.e(TAG, "could not execute process", e);
} finally {
stopSelf();
// eradicate process in critical section
synchronized (GPGAgentService.this) {
process = null;
}
}
}
}
@Override
public void onCreate() {
Log.d(TAG, "onCreate");
// Prepare environment for agent
AndroidHelper.envSetup(this);
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
// use critical section to avoid race conditions
synchronized (this) {
process = new AgentProcessThread();
process.start();
}
return START_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
// onBind() must return null, even if binder unused
return null;
}
}

+ 22
- 0
src/basic_api.cc View File

@ -96,5 +96,27 @@ JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_keyCompromized(
::key_compromized(session, _ident->fpr);
}
JNIEXPORT void JNICALL Java_org_pEp_jniadapter_Engine_importKey(
JNIEnv *env,
jobject obj,
jbyteArray key
)
{
PEP_SESSION session = (PEP_SESSION) callLongMethod(env, obj, "getHandle");
char *_key = to_string(env, key);
if(_key == NULL){
throw_pEp_Exception(env, PEP_OUT_OF_MEMORY);
return;
}
PEP_STATUS status = ::import_key(session, _key, strlen(_key));
if (status != PEP_STATUS_OK) {
throw_pEp_Exception(env, status);
return;
}
}
} // extern "C"

+ 6
- 1
src/gen_java_Engine.ysl2 View File

@ -36,8 +36,13 @@ tstylesheet {
private native «$itype» «@name»(«$pitype» «$pname»);
public «$jtype» «@name»(«$pjtype» «$pname») {
«$pitype» _«$pname» = new «$pitype»(«$pname»);
||
choose {
when "$ptype = 'string'"
|> «$pitype» _«$pname» = «$pname».getBytes();
otherwise
|> «$pitype» _«$pname» = new «$pitype»(«$pname»);
}
choose {
when "@type = 'void'"
|> «@name»(_«$pname»);


+ 10
- 2
src/gen_java_exceptions.ysl2 View File

@ -6,7 +6,11 @@ tstylesheet {
template "/" {
| package org.pEp.jniadapter;
|
| public class pEpException extends Exception { }
| public class pEpException extends Exception {
| public pEpException(String message) {
| super(message);
| }
| }
apply "namespace/exception[@name='pEp_status']", 0;
}
@ -17,7 +21,11 @@ tstylesheet {
document "org/pEp/jniadapter/{$name}.java", "text" {
| package org.pEp.jniadapter;
|
| class «$name» extends pEpException { }
| class «$name» extends pEpException {
| public «$name»(String message) {
| super(message);
| }
| }
}
}


+ 1
- 0
src/pEp.yml2 View File

@ -92,6 +92,7 @@ namespace pEp {
basic identity myself(identity ident);
basic identity updateIdentity(identity ident);
basic void keyCompromized(identity ident);
basic void importKey(string key);
};
struct message {


Loading…
Cancel
Save