ENGINE-179 early implementation of re_evaluate_message_rating(). Needs some testing. ENGINE-179
authorEdouard Tisserant <edouard@pep-project.org>
Thu, 01 Jun 2017 22:44:16 +0200
branchENGINE-179
changeset 18152ce849e5ca78
parent 1813 0dbbba72dfbb
child 1820 167f2913e770
ENGINE-179 early implementation of re_evaluate_message_rating(). Needs some testing.
src/message_api.c
src/message_api.h
     1.1 --- a/src/message_api.c	Thu Jun 01 19:57:30 2017 +0200
     1.2 +++ b/src/message_api.c	Thu Jun 01 22:44:16 2017 +0200
     1.3 @@ -1592,6 +1592,52 @@
     1.4      return status;
     1.5  }
     1.6  
     1.7 +PEP_STATUS amend_rating_according_to_sender_and_recipients(
     1.8 +    PEP_SESSION session,
     1.9 +    PEP_rating *rating,
    1.10 +    pEp_identity *sender,
    1.11 +    stringlist_t *recipients) {
    1.12 +    
    1.13 +    PEP_STATUS status = PEP_STATUS_OK;
    1.14 +
    1.15 +    if (*rating > PEP_rating_mistrust) {
    1.16 +        PEP_rating kl_rating = PEP_rating_undefined;
    1.17 +
    1.18 +        if (recipients)
    1.19 +            kl_rating = keylist_rating(session, recipients);
    1.20 +
    1.21 +        if (kl_rating <= PEP_rating_mistrust) {
    1.22 +            *rating = kl_rating;
    1.23 +        }
    1.24 +        else if (*rating >= PEP_rating_reliable &&
    1.25 +                 kl_rating < PEP_rating_reliable) {
    1.26 +            *rating = PEP_rating_unreliable;
    1.27 +        }
    1.28 +        else if (*rating >= PEP_rating_reliable &&
    1.29 +                 kl_rating >= PEP_rating_reliable) {
    1.30 +            if (!(sender && sender->user_id && sender->user_id[0])) {
    1.31 +                *rating = PEP_rating_unreliable;
    1.32 +            }
    1.33 +            else {
    1.34 +                char *fpr = recipients->value;
    1.35 +                pEp_identity *_sender = new_identity(sender->address, fpr,
    1.36 +                                                   sender->user_id, sender->username);
    1.37 +                if (_sender == NULL)
    1.38 +                    return PEP_OUT_OF_MEMORY;
    1.39 +                status = get_trust(session, _sender);
    1.40 +                if (_sender->comm_type != PEP_ct_unknown) {
    1.41 +                    *rating = worst_rating(_rating(_sender->comm_type, PEP_rating_undefined),
    1.42 +                              kl_rating);
    1.43 +                }
    1.44 +                free_identity(_sender);
    1.45 +                if (status == PEP_CANNOT_FIND_IDENTITY)
    1.46 +                   status = PEP_STATUS_OK;
    1.47 +            }
    1.48 +        }
    1.49 +    }
    1.50 +    return status;
    1.51 +}
    1.52 +
    1.53  
    1.54  DYNAMIC_API PEP_STATUS _decrypt_message(
    1.55          PEP_SESSION session,
    1.56 @@ -1982,45 +2028,13 @@
    1.57  
    1.58          *rating = decrypt_rating(decrypt_status);
    1.59  
    1.60 -        if (*rating > PEP_rating_mistrust) {
    1.61 -            PEP_rating kl_rating = PEP_rating_undefined;
    1.62 -
    1.63 -            if (_keylist)
    1.64 -                kl_rating = keylist_rating(session, _keylist);
    1.65 -
    1.66 -            if (kl_rating <= PEP_rating_mistrust) {
    1.67 -                *rating = kl_rating;
    1.68 -            }
    1.69 -            else if (*rating >= PEP_rating_reliable &&
    1.70 -                     kl_rating < PEP_rating_reliable) {
    1.71 -                *rating = PEP_rating_unreliable;
    1.72 -            }
    1.73 -            else if (*rating >= PEP_rating_reliable &&
    1.74 -                     kl_rating >= PEP_rating_reliable) {
    1.75 -                if (!(src->from && src->from->user_id && src->from->user_id[0])) {
    1.76 -                    *rating = PEP_rating_unreliable;
    1.77 -                }
    1.78 -                else {
    1.79 -                    char *fpr = _keylist->value;
    1.80 -                    pEp_identity *_from = new_identity(src->from->address, fpr,
    1.81 -                                                       src->from->user_id, src->from->username);
    1.82 -                    if (_from == NULL)
    1.83 -                        goto enomem;
    1.84 -                    status = get_trust(session, _from);
    1.85 -                    if (_from->comm_type != PEP_ct_unknown) {
    1.86 -                        *rating = worst_rating(_rating(_from->comm_type, PEP_rating_undefined),
    1.87 -                                  kl_rating);
    1.88 -                    }
    1.89 -                    free_identity(_from);
    1.90 -                    if (status == PEP_CANNOT_FIND_IDENTITY)
    1.91 -                       status = PEP_STATUS_OK;
    1.92 -                    if (status != PEP_STATUS_OK)
    1.93 -                    {
    1.94 -                        GOTO(pep_error);
    1.95 -                    }
    1.96 -                }
    1.97 -            }
    1.98 -        }
    1.99 +        status = amend_rating_according_to_sender_and_recipients(session,
   1.100 +                                                                 rating,
   1.101 +                                                                 src->from,
   1.102 +                                                                 _keylist);
   1.103 +
   1.104 +        if (status != PEP_STATUS_OK)
   1.105 +            GOTO(pep_error);
   1.106      }
   1.107      else
   1.108      {
   1.109 @@ -2624,3 +2638,137 @@
   1.110  
   1.111      return ERROR(status);
   1.112  }
   1.113 +
   1.114 +static PEP_rating string_to_rating(const char * rating)
   1.115 +{
   1.116 +    if (rating == NULL)
   1.117 +        return PEP_rating_undefined;
   1.118 +    if (strcmp(rating, "cannot_decrypt") == 0)
   1.119 +        return PEP_rating_cannot_decrypt;
   1.120 +    if (strcmp(rating, "have_no_key") == 0)
   1.121 +        return PEP_rating_have_no_key;
   1.122 +    if (strcmp(rating, "unencrypted") == 0)
   1.123 +        return PEP_rating_unencrypted;
   1.124 +    if (strcmp(rating, "unencrypted_for_some") == 0)
   1.125 +        return PEP_rating_unencrypted_for_some;
   1.126 +    if (strcmp(rating, "unreliable") == 0)
   1.127 +        return PEP_rating_unreliable;
   1.128 +    if (strcmp(rating, "reliable") == 0)
   1.129 +        return PEP_rating_reliable;
   1.130 +    if (strcmp(rating, "trusted") == 0)
   1.131 +        return PEP_rating_trusted;
   1.132 +    if (strcmp(rating, "trusted_and_anonymized") == 0)
   1.133 +        return PEP_rating_trusted_and_anonymized;
   1.134 +    if (strcmp(rating, "fully_anonymous") == 0)
   1.135 +        return PEP_rating_fully_anonymous;
   1.136 +    if (strcmp(rating, "mistrust") == 0)
   1.137 +        return PEP_rating_mistrust;
   1.138 +    if (strcmp(rating, "b0rken") == 0)
   1.139 +        return PEP_rating_b0rken;
   1.140 +    if (strcmp(rating, "under_attack") == 0)
   1.141 +        return PEP_rating_under_attack;
   1.142 +    return PEP_rating_undefined;
   1.143 +}
   1.144 +
   1.145 +static PEP_STATUS string_to_keylist(const char * skeylist, stringlist_t **keylist)
   1.146 +{
   1.147 +    if (skeylist == NULL || keylist == NULL)
   1.148 +        return PEP_ILLEGAL_VALUE;
   1.149 +
   1.150 +    stringlist_t *rkeylist = NULL;
   1.151 +    stringlist_t *_kcurr = NULL;
   1.152 +    const char * fpr_begin = skeylist;
   1.153 +    const char * fpr_end = NULL;
   1.154 +
   1.155 +    do {
   1.156 +        fpr_end = strstr(fpr_begin, ",");
   1.157 +        
   1.158 +        char * fpr = strndup(
   1.159 +            fpr_begin,
   1.160 +            (fpr_end == NULL) ? strlen(fpr_begin) : fpr_end - fpr_begin);
   1.161 +        
   1.162 +        if (fpr == NULL)
   1.163 +            goto enomem;
   1.164 +        
   1.165 +        _kcurr = stringlist_add(_kcurr, fpr);
   1.166 +        if (_kcurr == NULL) {
   1.167 +            free(fpr);
   1.168 +            goto enomem;
   1.169 +        }
   1.170 +        
   1.171 +        if (rkeylist == NULL)
   1.172 +            rkeylist = _kcurr;
   1.173 +        
   1.174 +        fpr_begin = fpr_end ? fpr_end + 1 : NULL;
   1.175 +        
   1.176 +    } while (fpr_begin);
   1.177 +    
   1.178 +    *keylist = rkeylist;
   1.179 +    return PEP_STATUS_OK;
   1.180 +    
   1.181 +enomem:
   1.182 +    free_stringlist(rkeylist);
   1.183 +    return PEP_OUT_OF_MEMORY;
   1.184 +}
   1.185 +
   1.186 +DYNAMIC_API PEP_STATUS re_evaluate_message_rating(
   1.187 +    PEP_SESSION session,
   1.188 +    message *msg,
   1.189 +    stringlist_t *x_keylist,
   1.190 +    PEP_rating x_enc_status,
   1.191 +    PEP_rating *rating
   1.192 +)
   1.193 +{
   1.194 +    PEP_STATUS status = PEP_STATUS_OK;
   1.195 +    stringlist_t *_keylist = x_keylist;
   1.196 +    bool must_free_keylist = false;
   1.197 +
   1.198 +    assert(session);
   1.199 +    assert(msg);
   1.200 +    assert(rating);
   1.201 +
   1.202 +    if (!(session && msg && rating))
   1.203 +        return ERROR(PEP_ILLEGAL_VALUE);
   1.204 +
   1.205 +    if (x_enc_status == PEP_rating_undefined){
   1.206 +        for (stringpair_list_t *i = msg->opt_fields; i && i->value ; i=i->next) {
   1.207 +            if (strcasecmp(i->value->key, "X-EncStatus") == 0){
   1.208 +                x_enc_status = string_to_rating(i->value->value);
   1.209 +                break;
   1.210 +            }
   1.211 +        }
   1.212 +    }
   1.213 +    if (x_enc_status == PEP_rating_undefined)
   1.214 +        return ERROR(PEP_ILLEGAL_VALUE);
   1.215 +
   1.216 +    PEP_rating _rating = x_enc_status;
   1.217 +
   1.218 +    if (x_keylist == NULL){
   1.219 +        for (stringpair_list_t *i = msg->opt_fields; i && i->value ; i=i->next) {
   1.220 +            if (strcasecmp(i->value->key, "X-KeyList") == 0){
   1.221 +                status = string_to_keylist(i->value->value, &_keylist);
   1.222 +                if (status != PEP_STATUS_OK)
   1.223 +                    GOTO(pep_error);
   1.224 +            }
   1.225 +        }
   1.226 +    }
   1.227 +    if (x_keylist == NULL)
   1.228 +        return ERROR(PEP_ILLEGAL_VALUE);
   1.229 +
   1.230 +
   1.231 +    status = amend_rating_according_to_sender_and_recipients(session,
   1.232 +                                                             &_rating,
   1.233 +                                                             msg->from,
   1.234 +                                                             _keylist);
   1.235 +    
   1.236 +    return ERROR(status);
   1.237 +
   1.238 +enomem:
   1.239 +    status = PEP_OUT_OF_MEMORY;
   1.240 +
   1.241 +pep_error:
   1.242 +    if (must_free_keylist)
   1.243 +        free_stringlist(_keylist);
   1.244 +
   1.245 +    return ERROR(status);
   1.246 +}
     2.1 --- a/src/message_api.h	Thu Jun 01 19:57:30 2017 +0200
     2.2 +++ b/src/message_api.h	Thu Jun 01 22:44:16 2017 +0200
     2.3 @@ -422,6 +422,35 @@
     2.4      const char* lang, char **words, bool full
     2.5  );
     2.6  
     2.7 +// re_evaluate_message_rating() - re-evaluate already decrypted message rating
     2.8 +//
     2.9 +//  parameters:
    2.10 +//      session (in)            session handle
    2.11 +//      msg (in)                message to get the rating for
    2.12 +//      x_keylist (in)          decrypted message recipients keys fpr
    2.13 +//      x_enc_status (in)       original rating for the decrypted message
    2.14 +//      rating (out)            rating for the message
    2.15 +//
    2.16 +//  return value:
    2.17 +//      PEP_ILLEGAL_VALUE       if decrypted message doesn't contain 
    2.18 +//                              X-EncStatus optional field and x_enc_status is 
    2.19 +//                              pEp_rating_udefined
    2.20 +//                              or if decrypted message doesn't contain 
    2.21 +//                              X-Keylist optional field and x_keylist is NULL
    2.22 +//      PEP_OUT_OF_MEMORY       if not enough memory could be allocated
    2.23 +//
    2.24 +//  caveat:
    2.25 +//      msg->from must point to a valid pEp_identity
    2.26 +//      the ownership of msg remains with the caller
    2.27 +//	    the ownership of x_keylist remains with to the caller
    2.28 +
    2.29 +DYNAMIC_API PEP_STATUS re_evaluate_message_rating(
    2.30 +    PEP_SESSION session,
    2.31 +    message *msg,
    2.32 +    stringlist_t *x_keylist,
    2.33 +    PEP_rating x_enc_status,
    2.34 +    PEP_rating *rating
    2.35 +);
    2.36  #ifdef __cplusplus
    2.37  }
    2.38  #endif