ENGINE-455: compilation ain't execution, but it compiles ENGINE-455
authorKrista Bennett <krista@pep-project.org>
Mon, 20 Aug 2018 12:01:21 +0200
branchENGINE-455
changeset 285846f167eebe58
parent 2828 eb82afc171ef
child 2859 53694809c009
ENGINE-455: compilation ain't execution, but it compiles
src/pgp_gpg.c
     1.1 --- a/src/pgp_gpg.c	Tue Aug 14 15:46:57 2018 +0200
     1.2 +++ b/src/pgp_gpg.c	Mon Aug 20 12:01:21 2018 +0200
     1.3 @@ -14,95 +14,120 @@
     1.4  static void *gpgme;
     1.5  static struct gpg_s gpg;
     1.6  
     1.7 -static bool ensure_config_values(stringlist_t *keys, stringlist_t *values, const char* config_file_path)
     1.8 -{
     1.9 -    static char buf[MAX_LINELENGTH];
    1.10 -    int r;
    1.11 +// typedef struct _pep_gpgme_val_list {
    1.12 +//     gpgme_conf_arg_t type;
    1.13 +//     void* value;
    1.14 +//     _pep_gpgme_val_list* next;
    1.15 +// } pep_gpgme_val_list_t;
    1.16 +// 
    1.17 +// static pep_gpgme_val_list_t* new_pep_conf_val(gpgme_conf_arg_t type,
    1.18 +//                                                 void* value) {
    1.19 +//     pep_gpgme_val_list_t* retval = calloc(1, sizeof(pep_gpgme_val_list_t));
    1.20 +//     if (!retval)
    1.21 +//         return NULL;
    1.22 +//     retval->type = type;
    1.23 +//     retval->value = value;
    1.24 +//     return retval;    
    1.25 +// }
    1.26 +// 
    1.27 +// static pep_gpgme_val_list_t* add_pep_conf_val(pep_gpgme_val_list_t* list, 
    1.28 +//                                               gpgme_conf_arg_t type,
    1.29 +//                                               void* value) {
    1.30 +//     pep_gpgme_val_list_t* newnode = new_pep_conf_val(type, value);
    1.31 +//     if (!newnode)
    1.32 +//         return NULL;
    1.33 +// 
    1.34 +//     if (list) {
    1.35 +//         pep_gpgme_val_list_t** last_next = &(list->next);
    1.36 +//         while (*last_next)
    1.37 +//             last_next = &((*last_next)->next);
    1.38 +// 
    1.39 +//         *last_next = new_node;
    1.40 +//     }
    1.41 +//     return newnode; 
    1.42 +// }
    1.43 +
    1.44 +// // the lists are never long, so this should be fine.
    1.45 +// static void free_pep_conf_val_list(pep_gpgme_val_list_t* head) {
    1.46 +//     if (head) {
    1.47 +//         free_pep_conf_val_list(head->next);
    1.48 +//         free(value);
    1.49 +//         free(head);
    1.50 +//     }
    1.51 +// }
    1.52 +
    1.53 +bloblist_t* make_conf_val(gpgme_conf_type_t type, const void* value) {    
    1.54 +    char* strval = NULL;
    1.55 +    void* otherval = NULL;
    1.56 +    switch(type) {
    1.57 +        case GPGME_CONF_NONE:
    1.58 +            strval = (char*)calloc(1,1);
    1.59 +            return new_bloblist(strval, 1, NULL, NULL); // BL placeholder 
    1.60 +        case GPGME_CONF_STRING:
    1.61 +        case GPGME_CONF_FILENAME:
    1.62 +        case GPGME_CONF_LDAP_SERVER:
    1.63 +        case GPGME_CONF_KEY_FPR:
    1.64 +        case GPGME_CONF_PUB_KEY:
    1.65 +        case GPGME_CONF_SEC_KEY:
    1.66 +        case GPGME_CONF_ALIAS_LIST:
    1.67 +            strval = strdup((const char*)value);
    1.68 +            if (!strval)
    1.69 +                return NULL;
    1.70 +            return new_bloblist(strval, strlen(strval), NULL, NULL);
    1.71 +        case GPGME_CONF_INT32:
    1.72 +        case GPGME_CONF_UINT32:
    1.73 +            otherval = calloc(1,4);
    1.74 +            if (!memcpy(otherval, value, 4))
    1.75 +                return NULL;
    1.76 +            return new_bloblist(otherval, 4, NULL, NULL);
    1.77 +        default:
    1.78 +            return NULL;
    1.79 +    }
    1.80 +}
    1.81 +
    1.82 +static bool ensure_config_values(PEP_SESSION session,
    1.83 +                                 gpgme_conf_comp_t configs, 
    1.84 +                                 const char* conf_name, 
    1.85 +                                 stringlist_t *keys, 
    1.86 +                                 bloblist_t *values)
    1.87 +{    
    1.88 +    gpgme_conf_comp_t curr_conf = configs;
    1.89 +    gpgme_conf_opt_t opt;
    1.90 +    gpgme_error_t gpgme_error;
    1.91      stringlist_t *_k;
    1.92 -    stringlist_t *_v;
    1.93 -    unsigned int i;
    1.94 -    unsigned int found = 0;
    1.95 -    bool eof_nl = 0;
    1.96 -    char * rest;
    1.97 -    char * token;
    1.98 -    char * s;
    1.99 -    const char* line_end;
   1.100 -
   1.101 -#ifdef WIN32
   1.102 -    line_end = "\r\n";
   1.103 -#else
   1.104 -    line_end = "\n";
   1.105 -#endif    
   1.106 -
   1.107 -    FILE *f = Fopen(config_file_path, "r");
   1.108 -    if (f == NULL && errno == ENOMEM)
   1.109 -        return false;
   1.110 -
   1.111 -    if (f != NULL) {
   1.112 -        int length = stringlist_length(keys);
   1.113 -
   1.114 -        // make sure we 1) have the same number of keys and values
   1.115 -        // and 2) we don't have more key/value pairs than
   1.116 -        // the size of the bitfield used to hold the indices
   1.117 -        // of key/value pairs matching keys in the config file.
   1.118 -        assert(length <= sizeof(unsigned int) * CHAR_BIT);
   1.119 -        assert(length == stringlist_length(values));
   1.120 -        if (!(length == stringlist_length(values) &&
   1.121 -              length <= sizeof(unsigned int) * CHAR_BIT)) {
   1.122 -            Fclose(f);
   1.123 -
   1.124 -            return false;
   1.125 -        }
   1.126 -
   1.127 -        while ((s = Fgets(buf, MAX_LINELENGTH, f))) {
   1.128 -            token = strtok_r(s, " \t\r\n", &rest);
   1.129 -            for (_k = keys, _v = values, i = 1;
   1.130 -                 _k != NULL;
   1.131 -                 _k = _k->next, _v = _v->next, i <<= 1) {
   1.132 -
   1.133 -                if (((found & i) != i) && token &&
   1.134 -                    (strncmp(token, _k->value, strlen(_k->value)) == 0)) {
   1.135 -                    found |= i;
   1.136 -                    break;
   1.137 +    bloblist_t *_v;
   1.138 +     
   1.139 +    while (curr_conf) {
   1.140 +        if (strcmp(curr_conf->name, conf_name) == 0) {
   1.141 +            for (_k = keys, _v = values; _k != NULL; _k = _k->next, _v = _v->next) {
   1.142 +                for (opt = curr_conf->options; opt; opt = opt->next) {
   1.143 +                    if (!(opt->flags & GPGME_CONF_GROUP) && strcmp(opt->name, _k->value) == 0) {
   1.144 +                        if (!opt->value) {
   1.145 +                            // Option has *not* been *explicitly* set. So we can set it.
   1.146 +                            gpgme_conf_arg_t new_val;
   1.147 +                            if (opt->type == GPGME_CONF_NONE)
   1.148 +                                gpgme_error = gpgme_conf_arg_new(&new_val, opt->type, NULL);    
   1.149 +                            else     
   1.150 +                                gpgme_error = gpgme_conf_arg_new(&new_val, opt->type, _v->value);
   1.151 +                                
   1.152 +                            if (gpgme_error != GPG_ERR_NO_ERROR)
   1.153 +                                return false;
   1.154 +                                
   1.155 +                            gpgme_error = gpgme_conf_opt_change(opt, 0, new_val);    
   1.156 +                            if (gpgme_error != GPG_ERR_NO_ERROR)
   1.157 +                                return false;
   1.158 +                        }
   1.159 +                        break;
   1.160 +                    }
   1.161                  }
   1.162              }
   1.163 -            if (feof(f)) {
   1.164 -                eof_nl = 1;
   1.165 -                break;
   1.166 -            }
   1.167 -        }
   1.168 -
   1.169 -        if (!s && ferror(f))
   1.170 -            return false;
   1.171 -        f = Freopen(config_file_path, "a", f);
   1.172 -    }
   1.173 -    else {
   1.174 -        f = Fopen(config_file_path, "w");
   1.175 -    }
   1.176 -
   1.177 -    assert(f);
   1.178 -    if (f == NULL)
   1.179 -        return false;
   1.180 -    
   1.181 -    if (eof_nl)
   1.182 -        r = Fprintf(f, line_end);
   1.183 -
   1.184 -    for (i = 1, _k = keys, _v = values; _k != NULL; _k = _k->next,
   1.185 -            _v = _v->next, i <<= 1) {
   1.186 -        if ((found & i) == 0) {
   1.187 -            r = Fprintf(f, "%s %s%s", _k->value, _v->value, line_end);
   1.188 -            assert(r >= 0);
   1.189 -            if (r < 0)
   1.190 +            gpgme_error_t gpgme_err = gpgme_op_conf_save(session->ctx, curr_conf);
   1.191 +            if (gpgme_err != GPG_ERR_NO_ERROR)
   1.192                  return false;
   1.193 +            return true;
   1.194          }
   1.195      }
   1.196 -
   1.197 -    r = Fclose(f);
   1.198 -    assert(r == 0);
   1.199 -    if (r != 0)
   1.200 -        return false;
   1.201 -
   1.202 -    return true;
   1.203 +    return false;    
   1.204  }
   1.205  
   1.206  char* _undot_address(const char* address) {
   1.207 @@ -238,37 +263,51 @@
   1.208      bool bResult;
   1.209  
   1.210      if (in_first) {
   1.211 +        
   1.212 +        gpgme_conf_comp_t configs; 
   1.213 +
   1.214 +        gpgme_error = gpgme_op_conf_load(session->ctx, &configs);
   1.215 +        
   1.216          stringlist_t *conf_keys   = new_stringlist("keyserver");
   1.217 -        stringlist_t *conf_values = new_stringlist("hkp://keys.gnupg.net");
   1.218 -
   1.219 +        bloblist_t   *conf_values = make_conf_val(GPGME_CONF_STRING,
   1.220 +                                                  "hkp://keys.gnupg.net");
   1.221 +
   1.222 +        bloblist_t** nextval = &(conf_values->next);
   1.223 +                                                          
   1.224          stringlist_add(conf_keys, "cert-digest-algo");
   1.225 -        stringlist_add(conf_values, "SHA256");
   1.226 +        *nextval = make_conf_val(GPGME_CONF_STRING, "SHA256");
   1.227 +        nextval = &((*nextval)->next);
   1.228  
   1.229          stringlist_add(conf_keys, "no-emit-version");
   1.230 -        stringlist_add(conf_values, "");
   1.231 -
   1.232 +        *nextval = make_conf_val(GPGME_CONF_NONE, NULL); // placeholder
   1.233 +        nextval = &((*nextval)->next);
   1.234 +        
   1.235          stringlist_add(conf_keys, "no-comments");
   1.236 -        stringlist_add(conf_values, "");
   1.237 +        *nextval = make_conf_val(GPGME_CONF_NONE, NULL); // placeholder
   1.238 +        nextval = &((*nextval)->next);
   1.239  
   1.240          stringlist_add(conf_keys, "personal-cipher-preferences");
   1.241 -        stringlist_add(conf_values, "AES AES256 AES192 CAST5");
   1.242 +        *nextval = make_conf_val(GPGME_CONF_STRING, "AES AES256 AES192 CAST5");
   1.243 +        nextval = &((*nextval)->next);
   1.244  
   1.245          stringlist_add(conf_keys, "personal-digest-preferences");
   1.246 -        stringlist_add(conf_values, "SHA256 SHA512 SHA384 SHA224");
   1.247 +        *nextval = make_conf_val(GPGME_CONF_STRING, "SHA256 SHA512 SHA384 SHA224");
   1.248 +        nextval = &((*nextval)->next);
   1.249  
   1.250          stringlist_add(conf_keys, "ignore-time-conflict");
   1.251 -        stringlist_add(conf_values, "");
   1.252 +        *nextval = make_conf_val(GPGME_CONF_NONE, NULL); // placeholder
   1.253 +        nextval = &((*nextval)->next);
   1.254  
   1.255          stringlist_add(conf_keys, "allow-freeform-uid");
   1.256 -        stringlist_add(conf_values, "");
   1.257 -
   1.258 -#if defined(WIN32) || defined(NDEBUG)
   1.259 -        bResult = ensure_config_values(conf_keys, conf_values, gpg_conf());
   1.260 -#else
   1.261 -        bResult = ensure_config_values(conf_keys, conf_values, gpg_conf(false));
   1.262 -#endif
   1.263 +        *nextval = make_conf_val(GPGME_CONF_NONE, NULL); // placeholder
   1.264 +        nextval = &((*nextval)->next);
   1.265 +
   1.266 +        bResult = ensure_config_values(session, configs, 
   1.267 +                                       "gpg", conf_keys, 
   1.268 +                                       conf_values);
   1.269 +        
   1.270          free_stringlist(conf_keys);
   1.271 -        free_stringlist(conf_values);
   1.272 +        free_bloblist(conf_values);
   1.273  
   1.274          assert(bResult);
   1.275          if (!bResult) {
   1.276 @@ -276,19 +315,22 @@
   1.277              goto pep_error;
   1.278          }
   1.279  
   1.280 +        uint32_t temp_uint = 300;
   1.281          conf_keys = new_stringlist("default-cache-ttl");
   1.282 -        conf_values = new_stringlist("300");
   1.283 -
   1.284 +        conf_values = make_conf_val(GPGME_CONF_UINT32, &temp_uint);
   1.285 +        nextval = &(conf_values->next);
   1.286 +
   1.287 +        temp_uint = 1200;
   1.288          stringlist_add(conf_keys, "max-cache-ttl");
   1.289 -        stringlist_add(conf_values, "1200");
   1.290 -
   1.291 -#if defined(WIN32) || defined(NDEBUG)
   1.292 -        bResult = ensure_config_values(conf_keys, conf_values, gpg_agent_conf());
   1.293 -#else        
   1.294 -        bResult = ensure_config_values(conf_keys, conf_values, gpg_agent_conf(false));
   1.295 -#endif
   1.296 +        *nextval = make_conf_val(GPGME_CONF_UINT32, &temp_uint);        
   1.297 +        nextval = &((*nextval)->next);
   1.298 +
   1.299 +        bResult = ensure_config_values(session, configs, 
   1.300 +                                       "gpg-agent", conf_keys, 
   1.301 +                                       conf_values);
   1.302 +        
   1.303          free_stringlist(conf_keys);
   1.304 -        free_stringlist(conf_values);
   1.305 +        free_bloblist(conf_values);
   1.306  
   1.307          assert(bResult);
   1.308          if (!bResult) {
   1.309 @@ -298,8 +340,6 @@
   1.310  
   1.311          gpgme = dlopen(LIBGPGME, RTLD_LAZY);
   1.312          if (gpgme == NULL) {
   1.313 -            // FIXME: Hotfix here?
   1.314 -            
   1.315              status = PEP_INIT_CANNOT_LOAD_GPGME;
   1.316              goto pep_error;
   1.317          }
   1.318 @@ -549,6 +589,13 @@
   1.319      }
   1.320      assert(session->ctx);
   1.321  
   1.322 +    gpgme_conf_comp_t configs;
   1.323 +    gpgme_error = gpgme_op_conf_load(session->ctx, &configs);
   1.324 +    if (gpgme_error != GPG_ERR_NO_ERROR) {
   1.325 +        status = PEP_INIT_GPGME_INIT_FAILED;
   1.326 +        goto pep_error;
   1.327 +    }
   1.328 +
   1.329      gpgme_error = gpg.gpgme_set_protocol(session->ctx, GPGME_PROTOCOL_OpenPGP);
   1.330      gpgme_error = _GPGERR(gpgme_error);
   1.331      assert(gpgme_error == GPG_ERR_NO_ERROR);