ENGINE-450 - fixing my merge mess ENGINE-450
authorKrista Bennett <krista@pep-project.org>
Mon, 30 Jul 2018 20:21:50 +0200
branchENGINE-450
changeset 27919e7e4d84b06c
parent 2787 c25afa6f22e3
parent 2790 9cbdd7143760
child 2794 a4fc10be53f7
ENGINE-450 - fixing my merge mess
src/pEpEngine.c
src/pEpEngine.h
src/pEp_internal.h
src/pgp_gpg.c
test/include/EngineTestSuite.h
test/src/EngineTestSuite.cc
test/src/SuiteMaker.cc
     1.1 --- a/src/pEp_internal.h	Mon Jul 30 19:28:52 2018 +0200
     1.2 +++ b/src/pEp_internal.h	Mon Jul 30 20:21:50 2018 +0200
     1.3 @@ -1,7 +1,12 @@
     1.4  // This file is under GNU General Public License 3.0
     1.5  // see LICENSE.txt
     1.6  
     1.7 -#define PEP_ENGINE_VERSION "0.9.0"
     1.8 +
     1.9 +// THESE MUST ALL BE CHANGED TOGETHER!!!!
    1.10 +#define PEP_ENGINE_VERSION "1.0.441"
    1.11 +#define PEP_ENGINE_MAJOR 1
    1.12 +#define PEP_ENGINE_MINOR 0
    1.13 +#define PEP_ENGINE_PATCH 441
    1.14  
    1.15  // maximum attachment size to import as key 1MB, maximum of 20 attachments
    1.16  
    1.17 @@ -128,6 +133,8 @@
    1.18  
    1.19      sqlite3_stmt *log;
    1.20      sqlite3_stmt *trustword;
    1.21 +    sqlite3_stmt *get_cached_engine_version;
    1.22 +    sqlite3_stmt *set_cached_engine_version;    
    1.23      sqlite3_stmt *get_identity;
    1.24      sqlite3_stmt *get_identity_without_trust_check;
    1.25      sqlite3_stmt *get_identities_by_address;
     2.1 --- a/src/pgp_gpg.c	Mon Jul 30 19:28:52 2018 +0200
     2.2 +++ b/src/pgp_gpg.c	Mon Jul 30 20:21:50 2018 +0200
     2.3 @@ -14,6 +14,234 @@
     2.4  static void *gpgme;
     2.5  static struct gpg_s gpg;
     2.6  
     2.7 +struct _str_ptr_and_bit {
     2.8 +    const char* key;
     2.9 +    int bit;
    2.10 +};
    2.11 +
    2.12 +typedef struct _str_ptr_and_bit str_ptr_and_bit;
    2.13 +
    2.14 +int strptrcmp(const void* a, const void* b) {
    2.15 +    return (int)((((str_ptr_and_bit*)(a))->key) - (((str_ptr_and_bit*)(b))->key));
    2.16 +}
    2.17 +
    2.18 +// This is in response to ENGINE-427. We should NOT be aiming to keep this here.
    2.19 +bool quickfix_config(stringlist_t* keys, const char* config_file_path) {
    2.20 +    static char buf[MAX_LINELENGTH];
    2.21 +    size_t num_keys = stringlist_length(keys);
    2.22 +
    2.23 +    // Open file
    2.24 +
    2.25 +    FILE *f = Fopen(config_file_path, "r");    
    2.26 +       
    2.27 +    if (f == NULL)
    2.28 +        return false;
    2.29 +
    2.30 +    int i;
    2.31 +    stringlist_t* _k;
    2.32 +    stringlist_t* lines = new_stringlist(NULL);
    2.33 +    int found = 0;
    2.34 +
    2.35 +    char* s = NULL;
    2.36 +
    2.37 +    // Go through every line in the file
    2.38 +    while ((s = Fgets(buf, MAX_LINELENGTH, f))) {
    2.39 +        // pointers to the keys found in this string
    2.40 +        str_ptr_and_bit* found_keys = (str_ptr_and_bit*)(calloc(num_keys, sizeof(str_ptr_and_bit)));
    2.41 +        int num_found_keys = 0;
    2.42 +
    2.43 +        char* rest;
    2.44 +        char* line_token = strtok_r(s, "\r\n", &rest);
    2.45 +        if (!line_token)
    2.46 +            line_token = s;
    2.47 +            
    2.48 +        if (*line_token == '#' || *line_token == '\0') {
    2.49 +            stringlist_add(lines, strdup(line_token));
    2.50 +            continue;
    2.51 +        }
    2.52 +
    2.53 +        bool only_key_on_line = false;
    2.54 +        for (_k = keys, i = 1; _k; _k = _k->next, i<<=1) {
    2.55 +            char* keypos = strstr(line_token, _k->value);
    2.56 +            if (!keypos)
    2.57 +                continue;
    2.58 +            size_t keystr_len = strlen(_k->value);
    2.59 +            char* nextpos = keypos + keystr_len;
    2.60 +            bool notkey = false;
    2.61 +            
    2.62 +            if (keypos != line_token) {
    2.63 +                char prevchar = *(keypos - 1);
    2.64 +                switch (prevchar) {
    2.65 +                    case '-':
    2.66 +                    case ':':
    2.67 +                    case '/':
    2.68 +                        notkey = true;
    2.69 +                        break;
    2.70 +                    default:
    2.71 +                        break;
    2.72 +                }
    2.73 +            }
    2.74 +
    2.75 +            if (*nextpos && !notkey) {
    2.76 +                char nextchar = *nextpos;
    2.77 +                switch (nextchar) {
    2.78 +                    case '-':
    2.79 +                    case ':':
    2.80 +                    case '/':
    2.81 +                        notkey = true;
    2.82 +                        break;
    2.83 +                    default:
    2.84 +                        break;
    2.85 +                }
    2.86 +            }
    2.87 +            else if (line_token == keypos) {
    2.88 +                only_key_on_line = true;
    2.89 +                if (!(found & i)) {
    2.90 +                    found |= i;
    2.91 +                    stringlist_add(lines, strdup(line_token));
    2.92 +                    num_found_keys++;
    2.93 +                }
    2.94 +                break;
    2.95 +            }
    2.96 +
    2.97 +            if (!notkey) {
    2.98 +                // Ok, it's not just the key with a null terminator. So...
    2.99 +                // add a pointer to the key to the list from this string
   2.100 +                found_keys[num_found_keys].key = keypos; 	
   2.101 +                found_keys[num_found_keys].bit = i;
   2.102 +                num_found_keys++;
   2.103 +            }
   2.104 +            
   2.105 +            // Check to see if there are more annoying occurences of this 
   2.106 +            // key in the string
   2.107 +            for (keypos = strstr(nextpos, _k->value); 
   2.108 +                keypos; keypos = strstr(nextpos, _k->value)) {
   2.109 +                notkey = false;
   2.110 +                nextpos = keypos + keystr_len;
   2.111 +                char prevchar = *(keypos - 1);
   2.112 +                switch (prevchar) {
   2.113 +                    case '-':
   2.114 +                    case ':':
   2.115 +                    case '/':
   2.116 +                        notkey = true;
   2.117 +                        break;
   2.118 +                    default:
   2.119 +                        break;
   2.120 +                }
   2.121 +                if (!notkey) {
   2.122 +                    char nextchar = *nextpos;
   2.123 +                    switch (nextchar) {
   2.124 +                        case '-':
   2.125 +                        case ':':
   2.126 +                        case '/':
   2.127 +                            notkey = true;
   2.128 +                            break;
   2.129 +                        default:
   2.130 +                            break;
   2.131 +                    }
   2.132 +                }    
   2.133 +                if (notkey)
   2.134 +                    continue;
   2.135 +                found_keys[num_found_keys].key = keypos; 	
   2.136 +                found_keys[num_found_keys].bit = i;
   2.137 +                num_found_keys++;     
   2.138 +            }
   2.139 +        }
   2.140 +        
   2.141 +        if (!only_key_on_line) {
   2.142 +            if (num_found_keys == 0)
   2.143 +                stringlist_add(lines, strdup(line_token));        
   2.144 +            else if (num_found_keys == 1 && (line_token == found_keys[0].key)) {
   2.145 +                if (!(found & found_keys[0].bit)) {
   2.146 +                    stringlist_add(lines, strdup(line_token)); 
   2.147 +                    found |= found_keys[0].bit;
   2.148 +                }
   2.149 +            }
   2.150 +            else {
   2.151 +                qsort(found_keys, num_found_keys, sizeof(str_ptr_and_bit), strptrcmp);
   2.152 +                int j;
   2.153 +                const char* curr_start = line_token;
   2.154 +                const char* next_start = NULL;
   2.155 +                for (j = 0; j < num_found_keys; j++, curr_start = next_start) {
   2.156 +                    next_start = found_keys[j].key;
   2.157 +                    if (curr_start == next_start)
   2.158 +                        continue;
   2.159 +                    size_t copy_len = next_start - curr_start;
   2.160 +                    const char* movable_end = next_start - 1;
   2.161 +                    while (copy_len > 0 && (*movable_end == ' ' || *movable_end == '\t' || *movable_end == '\0')) {
   2.162 +                        movable_end--;
   2.163 +                        copy_len--;
   2.164 +                    }
   2.165 +                    if (copy_len > 0) {
   2.166 +                        if (j == 0 || !(found & found_keys[j - 1].bit)) {
   2.167 +                            // if j is 0 here, the first thing in the string wasn't a key, or we'd have continued.
   2.168 +                            // otherwise, regardless of the value of j, we check that the "last" key (j-1) isn't already
   2.169 +                            // found and dealt with.
   2.170 +                            // Having passed that, we copy.
   2.171 +                            stringlist_add(lines, strndup(curr_start, copy_len));
   2.172 +                            if (j > 0)
   2.173 +                                found |= found_keys[j-1].bit;
   2.174 +                        }
   2.175 +                    }
   2.176 +                }
   2.177 +                if (!(found & found_keys[num_found_keys - 1].bit)) {
   2.178 +                    stringlist_add(lines, strdup(found_keys[num_found_keys - 1].key));
   2.179 +                    found |= found_keys[num_found_keys - 1].bit;
   2.180 +                }            
   2.181 +            }
   2.182 +        }
   2.183 +        free(found_keys);
   2.184 +        found_keys = NULL;
   2.185 +    } // End of file
   2.186 +    // then write all lines to file.
   2.187 +    const char* line_end;
   2.188 +#ifdef WIN32
   2.189 +    line_end = "\r\n";
   2.190 +#else
   2.191 +    line_end = "\n";
   2.192 +#endif    
   2.193 +    size_t cf_path_len = strlen(config_file_path);
   2.194 +    size_t new_buf_size = cf_path_len + 5; // + .old\0
   2.195 +    char* old_config_path_fname = (char*)calloc(new_buf_size, 1);
   2.196 +    if (!old_config_path_fname)
   2.197 +        return false;
   2.198 +    strlcpy(old_config_path_fname, config_file_path, new_buf_size);
   2.199 +    strlcat(old_config_path_fname, ".old", new_buf_size);
   2.200 +    int ret = Fclose(f);
   2.201 +    assert(ret == 0);
   2.202 +    if (ret != 0)
   2.203 +        return false;
   2.204 +    
   2.205 +    ret = rename(config_file_path, old_config_path_fname);
   2.206 +    assert(ret == 0);
   2.207 +    if (ret != 0)
   2.208 +        return false;
   2.209 +
   2.210 +    // Ok, now open the thing for writing.
   2.211 +    f = Fopen(config_file_path, "w");
   2.212 +    
   2.213 +    assert(f);
   2.214 +    if (f == NULL)
   2.215 +        return false;
   2.216 +  
   2.217 +    stringlist_t* cur_string;
   2.218 +    
   2.219 +    for (cur_string = lines; cur_string; cur_string = cur_string->next) {
   2.220 +        ret = Fprintf(f, "%s%s", cur_string->value, line_end);
   2.221 +        assert(ret >= 0);
   2.222 +        if (ret < 0)
   2.223 +            return false;
   2.224 +    }
   2.225 +    free_stringlist(lines); // FIXME: memory
   2.226 +    
   2.227 +    ret = Fclose(f);
   2.228 +    assert(ret == 0);
   2.229 +    if (ret != 0)
   2.230 +        return false;
   2.231 +
   2.232 +    return true;
   2.233 +}
   2.234 +
   2.235  static bool ensure_config_values(stringlist_t *keys, stringlist_t *values, const char* config_file_path)
   2.236  {
   2.237      static char buf[MAX_LINELENGTH];
   2.238 @@ -39,6 +267,7 @@
   2.239          return false;
   2.240  
   2.241      if (f != NULL) {
   2.242 +                
   2.243          int length = stringlist_length(keys);
   2.244  
   2.245          // make sure we 1) have the same number of keys and values
   2.246 @@ -262,11 +491,28 @@
   2.247          stringlist_add(conf_keys, "allow-freeform-uid");
   2.248          stringlist_add(conf_values, "");
   2.249  
   2.250 +
   2.251 +        // ENGINE-427 - quick fix here. This will be removed in a few
   2.252 +        // versions, but we need to clean up our mess.
   2.253 +        int compare_result = -1;
   2.254 +        status = compare_cached_engine_version_to_other(session,
   2.255 +                                                        &compare_result, 
   2.256 +                                                        1, 0, 441);            
   2.257 +
   2.258 +        bResult = true;
   2.259 +        // status != OK => no cached engine version, i.e. first-time run.
   2.260 +        if (compare_result < 0 && status == PEP_STATUS_OK)
   2.261  #if defined(WIN32) || defined(NDEBUG)
   2.262 -        bResult = ensure_config_values(conf_keys, conf_values, gpg_conf());
   2.263 +            bResult = quickfix_config(conf_keys, gpg_conf());
   2.264 +        if (bResult)
   2.265 +            bResult = ensure_config_values(conf_keys, conf_values, gpg_conf());
   2.266  #else
   2.267 -        bResult = ensure_config_values(conf_keys, conf_values, gpg_conf(false));
   2.268 +            bResult = quickfix_config(conf_keys, gpg_conf(false));
   2.269 +        if (bResult)
   2.270 +            bResult = ensure_config_values(conf_keys, conf_values, gpg_conf(false));
   2.271  #endif
   2.272 +        status = PEP_STATUS_OK;
   2.273 +        
   2.274          free_stringlist(conf_keys);
   2.275          free_stringlist(conf_values);
   2.276  
   2.277 @@ -282,10 +528,15 @@
   2.278          stringlist_add(conf_keys, "max-cache-ttl");
   2.279          stringlist_add(conf_values, "1200");
   2.280  
   2.281 +        if (compare_result < 0 && status == PEP_STATUS_OK)
   2.282  #if defined(WIN32) || defined(NDEBUG)
   2.283 -        bResult = ensure_config_values(conf_keys, conf_values, gpg_agent_conf());
   2.284 +            bResult = quickfix_config(conf_keys, gpg_agent_conf());
   2.285 +        if (bResult)
   2.286 +            bResult = ensure_config_values(conf_keys, conf_values, gpg_agent_conf());
   2.287  #else        
   2.288 -        bResult = ensure_config_values(conf_keys, conf_values, gpg_agent_conf(false));
   2.289 +            bResult = quickfix_config(conf_keys, gpg_agent_conf(false));
   2.290 +        if (bResult)
   2.291 +            bResult = ensure_config_values(conf_keys, conf_values, gpg_agent_conf(false));
   2.292  #endif
   2.293          free_stringlist(conf_keys);
   2.294          free_stringlist(conf_values);
   2.295 @@ -299,7 +550,6 @@
   2.296          gpgme = dlopen(LIBGPGME, RTLD_LAZY);
   2.297          if (gpgme == NULL) {
   2.298              // FIXME: Hotfix here?
   2.299 -            
   2.300              status = PEP_INIT_CANNOT_LOAD_GPGME;
   2.301              goto pep_error;
   2.302          }
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/test_files/450_bad_gpgagent_conf_0	Mon Jul 30 20:21:50 2018 +0200
     3.3 @@ -0,0 +1,3 @@
     3.4 +default-cache-ttl 398749
     3.5 +personal-cipher-preferences AES 
     3.6 +no-emit-version
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/test_files/450_bad_gpgagent_conf_1	Mon Jul 30 20:21:50 2018 +0200
     4.3 @@ -0,0 +1,6 @@
     4.4 +comment No Comment
     4.5 +keyid-format 0xlongmax-cache-ttl 300 
     4.6 +personal-cipher-preferences AES 
     4.7 +max-cache-ttl 500 
     4.8 +max-cache-ttl 2000 
     4.9 +allow-freeform-uid
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/test_files/450_bad_gpgagent_conf_2	Mon Jul 30 20:21:50 2018 +0200
     5.3 @@ -0,0 +1,6 @@
     5.4 +comment No Commentallow-freeform-uid
     5.5 +keyid-format 0xlongdefault-cache-ttl 1 
     5.6 +personal-cipher-preferences AES 
     5.7 +default_cache_ttl 1 
     5.8 +default_cache_ttl 1 
     5.9 +allow-freeform-uid
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/test_files/450_bad_gpgagent_conf_3	Mon Jul 30 20:21:50 2018 +0200
     6.3 @@ -0,0 +1,6 @@
     6.4 +comment No Commentallow-freeform-uidallow-freeform-uid
     6.5 +keyid-format 0xlongmax-cache-ttl 12 
     6.6 +personal-cipher-preferences AES 
     6.7 +max-cache-ttl 1 
     6.8 +max-cache-ttle 40000 
     6.9 +allow-freeform-uid
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/test_files/450_bad_gpgagent_conf_4	Mon Jul 30 20:21:50 2018 +0200
     7.3 @@ -0,0 +1,6 @@
     7.4 +comment No Commentallow-freeform-uidcert-digest-algo SHA256 default-cache-ttl 2000000-buttsallow-freeform-uid
     7.5 +keyid-format 0xlongdefault-cache-ttl 2000000 
     7.6 +personal-cipher-preferences AES 
     7.7 +default-cache-ttl 2000000 
     7.8 +default-cache-ttl 2000000 
     7.9 +allow-freeform-uid
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/test/test_files/450_bad_gpgagent_conf_5	Mon Jul 30 20:21:50 2018 +0200
     8.3 @@ -0,0 +1,6 @@
     8.4 +comment No Commentmax-cache-ttl 2000000max-cache-ttl 2000000max-cache-ttl 2000000
     8.5 +keyid-format 0xlongdefault-cache-ttl 2000000 
     8.6 +personal-cipher-preferences AES 
     8.7 +default-cache-ttl 2000000 
     8.8 +default-cache-ttl 2000000 
     8.9 +max-cache-ttl 2000000
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/test_files/450_bad_gpgagent_conf_6	Mon Jul 30 20:21:50 2018 +0200
     9.3 @@ -0,0 +1,2 @@
     9.4 +max-cache-ttl 2000000max-cache-ttl 2000000max-cache-ttl 2000000
     9.5 +max-cache-ttl 2000000