diff --git a/android/build.gradle b/android/build.gradle index da8455a..f058512 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -2,7 +2,8 @@ def pEpEngineSrc = hasProperty('pEpEngineSrc') ? pEpEngineSrc : "../../pEpEngine" def buildAutomatic = hasProperty('buildAutomatic') ? buildAutomatic : "true" -def threadsToUse = hasProperty('threadsToUse') ? threadsToUse : 1 +def threadsToUse = hasProperty('threadsToUse') ? + threadsToUse : Runtime.getRuntime().availableProcessors() def pEpEngineDB = new File(new File(pEpEngineSrc), 'db') @@ -77,7 +78,7 @@ android { jniDebuggable true externalNativeBuild { ndkBuild { - arguments "-j${threadsToUse}", 'NDK_LOG=1' + arguments "-j${threadsToUse}", 'NDK_LOG=1', 'NDK_DEBUG=1', 'NDEBUG=null' // arguments '-B', 'NDK_DEBUG=1', 'NDEBUG=null', 'NDK_LOG=1' } } diff --git a/android/external/Makefile.conf b/android/external/Makefile.conf index 60890e5..561134d 100644 --- a/android/external/Makefile.conf +++ b/android/external/Makefile.conf @@ -20,7 +20,7 @@ NETTLE_VERSION=3.4.1 ### Git deps repos EXTERNAL_GIT_REPOS += libetpan|https://github.com/fdik/libetpan.git?HEAD -EXTERNAL_GIT_REPOS += sequoia|https://gitlab.com/sequoia-pgp/sequoia.git?b5b783f58c9b6fdb26163cb7b236ee71cfef339e +EXTERNAL_GIT_REPOS += sequoia|https://gitlab.com/sequoia-pgp/sequoia.git?de497f59570437d448b293769eb57bf7a9741f30 ### Common variables #### Source code targets diff --git a/src/basic_api.cc b/src/basic_api.cc index 469b822..3d8d14d 100644 --- a/src/basic_api.cc +++ b/src/basic_api.cc @@ -9,6 +9,7 @@ #include "throw_pEp_exception.hh" #include "jniutils.hh" +#include "passphrase_callback.hh" extern "C" { using namespace pEp::JNIAdapter; @@ -33,11 +34,18 @@ JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Engine__1trustwords( char *words; size_t wsize; + PEP_STATUS status = PEP_STATUS_OK; + if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->me) - ::myself(session(), _ident); + status = passphraseWrap(::myself, session(), _ident); else - ::update_identity(session(), _ident); + status = passphraseWrap(::update_identity, session(), _ident); + } + + if (status != PEP_STATUS_OK) { + throw_pEp_Exception(env, status); + return NULL; } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -51,7 +59,9 @@ JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Engine__1trustwords( else lang = "en"; - PEP_STATUS status = ::trustwords(session(), _ident->fpr, lang, &words, &wsize, 10); + status = passphraseWrap(::trustwords, + session(), (const char *) _ident->fpr, lang, &words, &wsize, 10); + if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return NULL; @@ -76,7 +86,7 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1myself( pEp_identity *_ident = to_identity(env, ident); - PEP_STATUS status = ::myself(session(), _ident); + PEP_STATUS status = passphraseWrap(::myself, session(), _ident); if (status != PEP_STATUS_OK) { LOGD("Failed Myself: 0x%04x\\n", status); @@ -102,7 +112,7 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1updateIdentity pEp_identity *_ident = to_identity(env, ident); - ::update_identity(session(), _ident); + passphraseWrap(::update_identity, session(), _ident); return from_identity(env, _ident); } @@ -123,9 +133,9 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1setOwnKey( std::lock_guard l(*mutex_local); pEp_identity *_ident = to_identity(env, ident); - char *_fpr = to_string(env, fpr); + const char *_fpr = to_string(env, fpr); - PEP_STATUS status = ::set_own_key(session(), _ident, _fpr); + PEP_STATUS status = passphraseWrap(::set_own_key, session(), _ident, _fpr); if (status != PEP_STATUS_OK) { LOGD("Failed setOwnKey: 0x%04x\\n", status); @@ -152,11 +162,18 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyMistrusted( pEp_identity *_ident = to_identity(env, ident); + PEP_STATUS status = PEP_STATUS_OK; + if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->me) - ::myself(session(), _ident); + status = passphraseWrap(::myself, session(), _ident); else - ::update_identity(session(), _ident); + status = passphraseWrap(::update_identity, session(), _ident); + } + + if (status != PEP_STATUS_OK) { + throw_pEp_Exception(env, status); + return; } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -164,7 +181,7 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyMistrusted( return; } - ::key_mistrusted(session(), _ident); + passphraseWrap(::key_mistrusted, session(), _ident); } JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyResetTrust( @@ -183,11 +200,18 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyResetTrust( pEp_identity *_ident = to_identity(env, ident); + PEP_STATUS status = PEP_STATUS_OK; + if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->me) - ::myself(session(), _ident); + status = passphraseWrap(::myself, session(), _ident); else - ::update_identity(session(), _ident); + status = passphraseWrap(::update_identity, session(), _ident); + } + + if (status != PEP_STATUS_OK) { + throw_pEp_Exception(env, status); + return; } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -195,7 +219,7 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1keyResetTrust( return; } - ::key_reset_trust(session(), _ident); + passphraseWrap(::key_reset_trust, session(), _ident); } JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustPersonalKey( @@ -214,11 +238,18 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustPersonalKey( pEp_identity *_ident = to_identity(env, ident); + PEP_STATUS status = PEP_STATUS_OK; + if (_ident->fpr == NULL || _ident->fpr[0] == 0) { if (_ident->me) - ::myself(session(), _ident); + status = passphraseWrap(::myself, session(), _ident); else - ::update_identity(session(), _ident); + status = passphraseWrap(::update_identity, session(), _ident); + } + + if (status != PEP_STATUS_OK) { + throw_pEp_Exception(env, status); + return; } if (_ident->fpr == NULL || _ident->fpr[0] == 0) { @@ -226,7 +257,7 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustPersonalKey( return; } - ::trust_personal_key(session(), _ident); + passphraseWrap(::trust_personal_key, session(), _ident); } JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustOwnKey( @@ -250,7 +281,7 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1trustOwnKey( return; } - ::trust_own_key(session(), _ident); + passphraseWrap(::trust_own_key, session(), _ident); } JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1importKey( @@ -268,7 +299,7 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1importKey( std::lock_guard l(*mutex_local); size_t _size = (size_t) env->GetArrayLength(key); - char *_key = (char *) env->GetByteArrayElements(key, NULL); + const char *_key = (char *) env->GetByteArrayElements(key, NULL); if(_key == NULL){ throw_pEp_Exception(env, PEP_OUT_OF_MEMORY); @@ -277,7 +308,7 @@ JNIEXPORT jobject JNICALL Java_foundation_pEp_jniadapter_Engine__1importKey( identity_list *_identities; - PEP_STATUS status = ::import_key(session(), _key, _size, &_identities); + PEP_STATUS status = passphraseWrap(::import_key, session(), _key, _size, &_identities); if (status != PEP_STATUS_OK && status != PEP_KEY_IMPORTED) { throw_pEp_Exception(env, status); return NULL; @@ -342,14 +373,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1blacklist_1add( } std::lock_guard l(*mutex_local); - char *_fpr = to_string(env, fpr); + const char *_fpr = to_string(env, fpr); if(_fpr == NULL){ throw_pEp_Exception(env, PEP_OUT_OF_MEMORY); return; } - PEP_STATUS status = ::blacklist_add(session(), _fpr); + PEP_STATUS status = passphraseWrap(::blacklist_add, session(), _fpr); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return; @@ -371,14 +402,14 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1blacklist_1delete } std::lock_guard l(*mutex_local); - char *_fpr = to_string(env, fpr); + const char *_fpr = to_string(env, fpr); if(_fpr == NULL){ throw_pEp_Exception(env, PEP_OUT_OF_MEMORY); return; } - PEP_STATUS status = ::blacklist_delete(session(), _fpr); + PEP_STATUS status = passphraseWrap(::blacklist_delete, session(), _fpr); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return; @@ -400,7 +431,7 @@ JNIEXPORT jboolean JNICALL Java_foundation_pEp_jniadapter_Engine__1blacklist_1is } std::lock_guard l(*mutex_local); - char *_fpr = to_string(env, fpr); + const char *_fpr = to_string(env, fpr); bool _listed = 0; if(_fpr == NULL){ @@ -408,7 +439,7 @@ JNIEXPORT jboolean JNICALL Java_foundation_pEp_jniadapter_Engine__1blacklist_1is return 0; } - PEP_STATUS status = ::blacklist_is_listed(session(), _fpr, &_listed); + PEP_STATUS status = passphraseWrap(::blacklist_is_listed, session(), _fpr, &_listed); if (status != PEP_STATUS_OK) { throw_pEp_Exception(env, status); return 0; @@ -435,7 +466,7 @@ JNIEXPORT jbyteArray JNICALL Java_foundation_pEp_jniadapter_Engine__1getCrashdum int _maxlines = (int) maxlines; char *_logdata; - PEP_STATUS status = ::get_crashdump_log(session(), _maxlines, &_logdata); + PEP_STATUS status = passphraseWrap(::get_crashdump_log, session(), _maxlines, &_logdata); if ((status > PEP_STATUS_OK && status < PEP_UNENCRYPTED) || status < PEP_STATUS_OK || status >= PEP_TRUSTWORD_NOT_FOUND) { @@ -525,6 +556,7 @@ JNIEXPORT void JNICALL Java_foundation_pEp_jniadapter_Engine__1config_1passphras return ; } + } } // extern "C" diff --git a/src/gen_cpp_Engine.ysl2 b/src/gen_cpp_Engine.ysl2 index 7dd15d9..3e52f11 100644 --- a/src/gen_cpp_Engine.ysl2 +++ b/src/gen_cpp_Engine.ysl2 @@ -270,6 +270,7 @@ tstylesheet { const "dir", "name(*[1])"; const "type", "name(*[2])"; const "name", "name(*[3])"; + const "const", "name(*[4])"; choose { when "$type = 'message'" @@ -280,10 +281,18 @@ tstylesheet { | bool _«$name» = (bool) «$name»; when "$type='int'" | int _«$name» = (int) «$name»; + when "$type='uint'" + | auto _«$name» = (unsigned int) «$name»; when "$type='string'" | const char *_«$name» = to_string(env, «$name»); - otherwise - | √$type *_«$name» = to_«$type»(env, «$name»); + otherwise { + choose { + when "$const" + | const √$type *_«$name» = to_«$type»(env, «$name»); + otherwise + | √$type *_«$name» = to_«$type»(env, «$name»); + } + } } } diff --git a/src/pEp.yml2 b/src/pEp.yml2 index 8810026..c3022fa 100644 --- a/src/pEp.yml2 +++ b/src/pEp.yml2 @@ -119,14 +119,14 @@ namespace pEp { inout int flags ); - method re_evaluate_message_rating( + method cached=true re_evaluate_message_rating( in message src, - Cconst stringlist x_keylist "NULL", + Cconst stringlist x_keylist "static_cast(nullptr)", Cconst Rating x_enc_status "PEP_rating_undefined", returns Rating rating ); - method outgoing_message_rating( + method cached=true outgoing_message_rating( in message msg, returns Rating rating ); @@ -136,18 +136,18 @@ namespace pEp { returns Rating rating ); - method get_identity( + method cached=true get_identity( in string address, in string userid, returns identity ident ); - method identity_rating( + method cached=true identity_rating( in identity ident, returns Rating rating ); - method blacklist_retrieve( + method cached=true blacklist_retrieve( returns stringlist blacklist ); @@ -157,34 +157,36 @@ namespace pEp { returns identity ident ); - method OpenPGP_list_keyinfo( + method cached=true OpenPGP_list_keyinfo( in string pattern, returns stringpairlist keyinfoList ); - method set_identity_flags( + //TODO Move to use IdentityFlag instead of ints + method cached=true set_identity_flags( in identity ident, - in int flags + in uint flags ); - method unset_identity_flags( + method cached=true unset_identity_flags( in identity ident, - in int flags + in uint flags ); - method own_identities_retrieve( + method cached=true own_identities_retrieve( returns identitylist identities ); - method get_trustwords( - in identity id1, - in identity id2, + + method cached=true get_trustwords( + in identity id1 const, + in identity id2 const, in string lang, returns sstring words, in bool full ); - method get_trustwords_for_fprs( + method cached=true get_trustwords_for_fprs( in string fpr1, in string fpr2, in string lang, @@ -201,13 +203,13 @@ namespace pEp { in bool full ); - method get_languagelist( + method cached=true get_languagelist( returns string languagelist ); // this function is not related to key reset - method key_reset_trust( + method cached=true key_reset_trust( in identity ident ); @@ -223,14 +225,14 @@ namespace pEp { method cached=true key_reset_all_own_keys(); - method deliverHandshakeResult( + method cached=true deliverHandshakeResult( in SyncHandshakeResult shr, - in identitylist identities + in identitylist identities const ); - method leave_device_group(); + method cached=true leave_device_group(); - method enable_identity_for_sync( + method cached=true enable_identity_for_sync( in identity ident ); diff --git a/src/passphrase_callback.hh b/src/passphrase_callback.hh index 357b2c6..8482077 100644 --- a/src/passphrase_callback.hh +++ b/src/passphrase_callback.hh @@ -1,3 +1,5 @@ +#pragma once +#include namespace pEp { @@ -5,5 +7,9 @@ namespace pEp { char* passphraseRequiredCallback(); + template PEP_STATUS passphraseWrap( + PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a); }; -}; \ No newline at end of file +}; + +#include "passphrase_callback.hxx" \ No newline at end of file diff --git a/src/passphrase_callback.hxx b/src/passphrase_callback.hxx new file mode 100644 index 0000000..20bfa36 --- /dev/null +++ b/src/passphrase_callback.hxx @@ -0,0 +1,41 @@ +#pragma once + +#include "passphrase_callback.hh" + +namespace pEp { + namespace JNIAdapter { + + template PEP_STATUS passphraseWrap( + PEP_STATUS f(PEP_SESSION, A...), PEP_SESSION session, A... a) { + pEpLog("cached passphrase mode"); + bool retryAgain = false; + int maxRetries = 3; + int retryCount = 0; + PEP_STATUS status; + do { + // the actual target function + pEpLog("calling passphrase_cache.api from basic_api"); + status = passphrase_cache.api(f, session, a...); + pEpLog("PEP_STATUS:" << status); + if (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE) { + pEpLog("none of the cached passphrases worked"); + if (retryCount < maxRetries) { + // call the app + char *_passphrase = passphraseRequiredCallback(); + pEpLog("callback returned, config_passphrase() with new passphrase"); + PEP_STATUS status = ::config_passphrase(session, + passphrase_cache.add(_passphrase)); + retryAgain = true; + retryCount++; + } else { + pEpLog("max retries reached:" << maxRetries); + retryAgain = false; + } + } else { + retryAgain = false; + } + } while (retryAgain); + return status; + } + } +} \ No newline at end of file diff --git a/src/types_c.ysl2 b/src/types_c.ysl2 index 1ec81ea..0d2497f 100644 --- a/src/types_c.ysl2 +++ b/src/types_c.ysl2 @@ -17,6 +17,7 @@ function "toC" { when "$type='Rating'" > PEP_rating when "$type='SyncHandshakeResult'" > sync_handshake_result when "$type='CipherSuite'" > PEP_CIPHER_SUITE + when "$type='uint'" > uint otherwise value "$type"; } @@ -31,6 +32,7 @@ function "jni_type" { when "$type = 'string' or $type = 'sstring'" > jbyteArray when "$type='bool'" > jboolean when "$type='int'" > jint + when "$type='uint'" > jint otherwise > jobject } } diff --git a/src/types_java.ysl2 b/src/types_java.ysl2 index a6806e5..6e67660 100644 --- a/src/types_java.ysl2 +++ b/src/types_java.ysl2 @@ -4,6 +4,7 @@ function "toJava" { choose { when "$type='bool'" > Boolean when "$type='int'" > int + when "$type='uint'" > int when "$type='string' or $type='sstring'" > String when "$type='timestamp'" > Date when "$type='void'" > void