merged in default ENGINE-214
authorKrista Bennett <krista@pep-project.org>
Tue, 03 Oct 2017 17:00:37 +0200
branchENGINE-214
changeset 2131334139882a97
parent 2122 e570aa766e5f
parent 2130 9943fcb0d532
child 2135 9efe970213f2
merged in default
src/pEp_internal.h
     1.1 --- a/build-mac/pEpEngine.xcodeproj/project.pbxproj	Sat Sep 30 17:32:21 2017 +0200
     1.2 +++ b/build-mac/pEpEngine.xcodeproj/project.pbxproj	Tue Oct 03 17:00:37 2017 +0200
     1.3 @@ -123,7 +123,6 @@
     1.4  		64A826811B455D0800EECAF0 /* pEpEngine.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A826601B455D0800EECAF0 /* pEpEngine.c */; };
     1.5  		64A826821B455D0800EECAF0 /* pgp_netpgp.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A826631B455D0800EECAF0 /* pgp_netpgp.c */; };
     1.6  		64A826831B455D0800EECAF0 /* platform_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A826651B455D0800EECAF0 /* platform_unix.c */; };
     1.7 -		64A826851B455D0800EECAF0 /* sqlite3.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A8266B1B455D0800EECAF0 /* sqlite3.c */; settings = {COMPILER_FLAGS = "-DSQLITE_THREADSAFE=1 -DSQLITE_TEMP_STORE=3"; }; };
     1.8  		64A826861B455D0800EECAF0 /* stringlist.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A8266D1B455D0800EECAF0 /* stringlist.c */; };
     1.9  		64A826871B455D0800EECAF0 /* stringpair.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A8266F1B455D0800EECAF0 /* stringpair.c */; };
    1.10  		64A826881B455D0800EECAF0 /* timestamp.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A826711B455D0800EECAF0 /* timestamp.c */; };
    1.11 @@ -815,7 +814,6 @@
    1.12  				64A826861B455D0800EECAF0 /* stringlist.c in Sources */,
    1.13  				4354FF651D6EDF300033069C /* sync_impl.c in Sources */,
    1.14  				64A8267E1B455D0800EECAF0 /* message_api.c in Sources */,
    1.15 -				64A826851B455D0800EECAF0 /* sqlite3.c in Sources */,
    1.16  				43E9BC7F1DB6720E00AD2352 /* UpdateRequest.c in Sources */,
    1.17  				646C41361D510CD800C63EFF /* Version.c in Sources */,
    1.18  				646C41081D510CD800C63EFF /* constr_TYPE.c in Sources */,
    1.19 @@ -933,7 +931,7 @@
    1.20  				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
    1.21  				ENABLE_STRICT_OBJC_MSGSEND = YES;
    1.22  				ENABLE_TESTABILITY = YES;
    1.23 -				GCC_C_LANGUAGE_STANDARD = gnu99;
    1.24 +				GCC_C_LANGUAGE_STANDARD = c11;
    1.25  				GCC_DYNAMIC_NO_PIC = NO;
    1.26  				GCC_NO_COMMON_BLOCKS = YES;
    1.27  				GCC_OPTIMIZATION_LEVEL = 0;
    1.28 @@ -959,6 +957,7 @@
    1.29  				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
    1.30  				MTL_ENABLE_DEBUG_INFO = YES;
    1.31  				ONLY_ACTIVE_ARCH = YES;
    1.32 +				OTHER_CFLAGS = "-DSQLITE3_FROM_OS";
    1.33  				SDKROOT = iphoneos;
    1.34  			};
    1.35  			name = Debug;
    1.36 @@ -986,7 +985,7 @@
    1.37  				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
    1.38  				ENABLE_NS_ASSERTIONS = NO;
    1.39  				ENABLE_STRICT_OBJC_MSGSEND = YES;
    1.40 -				GCC_C_LANGUAGE_STANDARD = gnu99;
    1.41 +				GCC_C_LANGUAGE_STANDARD = c11;
    1.42  				GCC_NO_COMMON_BLOCKS = YES;
    1.43  				GCC_PREPROCESSOR_DEFINITIONS = "USE_NETPGP=1";
    1.44  				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
    1.45 @@ -1006,6 +1005,7 @@
    1.46  				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
    1.47  				MTL_ENABLE_DEBUG_INFO = NO;
    1.48  				ONLY_ACTIVE_ARCH = NO;
    1.49 +				OTHER_CFLAGS = "-DSQLITE3_FROM_OS";
    1.50  				SDKROOT = iphoneos;
    1.51  				VALIDATE_PRODUCT = YES;
    1.52  			};
     2.1 --- a/src/keymanagement.c	Sat Sep 30 17:32:21 2017 +0200
     2.2 +++ b/src/keymanagement.c	Tue Oct 03 17:00:37 2017 +0200
     2.3 @@ -723,12 +723,38 @@
     2.4      }
     2.5      else
     2.6      {
     2.7 +        // for undo
     2.8 +        if (session->cached_mistrusted)
     2.9 +            free(session->cached_mistrusted);
    2.10 +        session->cached_mistrusted = identity_dup(ident);
    2.11          status = mark_as_compromized(session, ident->fpr);
    2.12      }
    2.13  
    2.14      return status;
    2.15  }
    2.16  
    2.17 +DYNAMIC_API PEP_STATUS undo_last_mistrust(PEP_SESSION session) {
    2.18 +    assert(session);
    2.19 +    
    2.20 +    if (!session)
    2.21 +        return PEP_ILLEGAL_VALUE;
    2.22 +    
    2.23 +    PEP_STATUS status = PEP_STATUS_OK;
    2.24 +        
    2.25 +    pEp_identity* cached_ident = session->cached_mistrusted;
    2.26 +    
    2.27 +    if (!cached_ident)
    2.28 +        status = PEP_CANNOT_FIND_IDENTITY;
    2.29 +    else {
    2.30 +        status = set_identity(session, cached_ident);            
    2.31 +        free_identity(session->cached_mistrusted);
    2.32 +    }
    2.33 +    
    2.34 +    session->cached_mistrusted = NULL;
    2.35 +
    2.36 +    return status;
    2.37 +}
    2.38 +
    2.39  DYNAMIC_API PEP_STATUS key_reset_trust(
    2.40          PEP_SESSION session,
    2.41          pEp_identity *ident
     3.1 --- a/src/keymanagement.h	Sat Sep 30 17:32:21 2017 +0200
     3.2 +++ b/src/keymanagement.h	Tue Oct 03 17:00:37 2017 +0200
     3.3 @@ -125,17 +125,35 @@
     3.4      );
     3.5  
     3.6  
     3.7 -// key_mistrusted() - mark key as being compromized
     3.8 +// key_mistrusted() - mark key as being compromised
     3.9  //
    3.10  //  parameters:
    3.11  //      session (in)        session to use
    3.12 -//      ident (in)          person and key which was compromized
    3.13 +//      ident (in)          person and key which was compromised
    3.14  
    3.15  DYNAMIC_API PEP_STATUS key_mistrusted(
    3.16          PEP_SESSION session,
    3.17          pEp_identity *ident
    3.18      );
    3.19  
    3.20 +// undo_last_mistrust() - reset identity and trust status for the last
    3.21 +//                        identity in this session marked as mistrusted
    3.22 +//                        to their cached values from the time of mistrust
    3.23 +//  parameters:
    3.24 +//      session (in)        session to use
    3.25 +//
    3.26 +//  return value:
    3.27 +//      PEP_STATUS_OK if identity and trust were successfully restored.
    3.28 +//      Otherwise, error status from attempts to set.
    3.29 +//
    3.30 +//  caveat:
    3.31 +//      only works for this session, and only once. cache is invalidated
    3.32 +//      upon use.
    3.33 +//
    3.34 +//      WILL NOT WORK ON MISTRUSTED OWN KEY
    3.35 +
    3.36 +DYNAMIC_API PEP_STATUS undo_last_mistrust(PEP_SESSION session);
    3.37 +
    3.38  
    3.39  // trust_personal_key() - mark a key as trusted with a person
    3.40  //
     4.1 --- a/src/pEpEngine.c	Sat Sep 30 17:32:21 2017 +0200
     4.2 +++ b/src/pEpEngine.c	Tue Oct 03 17:00:37 2017 +0200
     4.3 @@ -8,7 +8,7 @@
     4.4  #include "blacklist.h"
     4.5  #include "sync_fsm.h"
     4.6  
     4.7 -static int init_count = -1;
     4.8 +static volatile int init_count = -1;
     4.9  
    4.10  // sql overloaded functions - modified from sqlite3.c
    4.11  static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
    4.12 @@ -264,9 +264,25 @@
    4.13      // a little race condition - but still a race condition
    4.14      // mitigated by calling caveat (see documentation)
    4.15  
    4.16 -    ++init_count;
    4.17 -    if (init_count == 0)
    4.18 +    // this increment is made atomic IN THE ADAPTERS by
    4.19 +    // guarding the call to init with the appropriate mutex.
    4.20 +    int _count = ++init_count;
    4.21 +    if (_count == 0)
    4.22          in_first = true;
    4.23 +    
    4.24 +    // Race contition mitigated by calling caveat starts here :
    4.25 +    // If another call to init() preempts right now, then preemptive call
    4.26 +    // will have in_first false, will not create SQL tables, and following
    4.27 +    // calls relying on those tables will fail.
    4.28 +    //
    4.29 +    // Therefore, as above, adapters MUST guard init() with a mutex.
    4.30 +    // 
    4.31 +    // Therefore, first session
    4.32 +    // is to be created and last session to be deleted alone, and not
    4.33 +    // concurently to other sessions creation or deletion.
    4.34 +    // We expect adapters to enforce this either by implicitely creating a
    4.35 +    // client session, or by using synchronization primitive to protect
    4.36 +    // creation/deletion of first/last session from the app.
    4.37  
    4.38      assert(session);
    4.39      if (session == NULL)
    4.40 @@ -772,19 +788,19 @@
    4.41  DYNAMIC_API void release(PEP_SESSION session)
    4.42  {
    4.43      bool out_last = false;
    4.44 -
    4.45 -    assert(init_count >= 0);
    4.46 +    int _count = --init_count;
    4.47 +    
    4.48 +    assert(_count >= -1);
    4.49      assert(session);
    4.50  
    4.51 -    if (!((init_count >= 0) && session))
    4.52 +    if (!((_count >= -1) && session))
    4.53          return;
    4.54  
    4.55      // a small race condition but still a race condition
    4.56      // mitigated by calling caveat (see documentation)
    4.57 -
    4.58 -    if (init_count == 0)
    4.59 +    // (release() is to be guarded by a mutex by the caller)
    4.60 +    if (_count == -1)
    4.61          out_last = true;
    4.62 -    --init_count;
    4.63  
    4.64      if (session) {
    4.65          if (session->sync_state != DeviceState_state_NONE)
     5.1 --- a/src/pEpEngine.h	Sat Sep 30 17:32:21 2017 +0200
     5.2 +++ b/src/pEpEngine.h	Tue Oct 03 17:00:37 2017 +0200
     5.3 @@ -129,6 +129,9 @@
     5.4  //                                            opened
     5.5  //
     5.6  //  caveat:
     5.7 +//      THE CALLER MUST GUARD THIS CALL EXTERNALLY WITH A MUTEX. release() should
     5.8 +//      be similarly guarded.
     5.9 +//
    5.10  //      the pointer is valid only if the return value is PEP_STATUS_OK
    5.11  //      in other case a NULL pointer will be returned; a valid handle must
    5.12  //      be released using release() when it's no longer needed
    5.13 @@ -145,6 +148,9 @@
    5.14  //        session (in)    session handle to release
    5.15  //
    5.16  //    caveat:
    5.17 +//        THE CALLER MUST GUARD THIS CALL EXTERNALLY WITH A MUTEX. init() should
    5.18 +//        be similarly guarded.
    5.19 +//       
    5.20  //        the last release() can be called only when all other release() calls
    5.21  //        are done
    5.22  
    5.23 @@ -856,6 +862,7 @@
    5.24  
    5.25  DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity);
    5.26  
    5.27 +
    5.28  PEP_STATUS set_trust(PEP_SESSION session, 
    5.29                              const char* user_id,
    5.30                              const char* fpr, 
     6.1 --- a/src/pEp_internal.h	Sat Sep 30 17:32:21 2017 +0200
     6.2 +++ b/src/pEp_internal.h	Tue Oct 03 17:00:37 2017 +0200
     6.3 @@ -186,6 +186,9 @@
     6.4      bool unencrypted_subject;
     6.5      bool keep_sync_msg;
     6.6      bool service_log;
     6.7 +
     6.8 +    // mistrust undo cache
     6.9 +    pEp_identity* cached_mistrusted;
    6.10      
    6.11  #ifdef DEBUG_ERRORSTACK
    6.12      stringlist_t* errorstack;
     7.1 --- a/src/platform_unix.c	Sat Sep 30 17:32:21 2017 +0200
     7.2 +++ b/src/platform_unix.c	Tue Oct 03 17:00:37 2017 +0200
     7.3 @@ -297,8 +297,14 @@
     7.4              fd = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
     7.5  
     7.6              if(fd>0) {
     7.7 -                write(fd, gpg_conf_empty, strlen(gpg_conf_empty));
     7.8 +                ssize_t res;
     7.9 +                len = strlen(gpg_conf_empty);
    7.10 +                res = write(fd, gpg_conf_empty, len);
    7.11                  close(fd);
    7.12 +                if(res < len) {
    7.13 +                    assert(0);
    7.14 +                    return false;
    7.15 +                }
    7.16              }
    7.17          }
    7.18  
    7.19 @@ -344,8 +350,14 @@
    7.20              fd = open(agent_path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
    7.21  
    7.22              if(fd>0) {
    7.23 -                write(fd, gpg_conf_empty, strlen(gpg_conf_empty));
    7.24 +                ssize_t res;
    7.25 +                len = strlen(gpg_conf_empty);
    7.26 +                res = write(fd, gpg_conf_empty, len);
    7.27                  close(fd);
    7.28 +                if(res < len) {
    7.29 +                    assert(0);
    7.30 +                    return false;
    7.31 +                }
    7.32              }
    7.33          }
    7.34          done = true;