merge sync
authorKrista Bennett <krista@pep-project.org>
Thu, 22 Nov 2018 13:24:28 +0100
branchsync
changeset 3150a99c04f1eee7
parent 3149 29373ec25400
parent 3147 a76766d1ed47
child 3151 9a6e62340dab
child 3154 f4961c0625a8
merge
src/pgp_netpgp.c
     1.1 --- a/src/baseprotocol.c	Thu Nov 22 13:23:26 2018 +0100
     1.2 +++ b/src/baseprotocol.c	Thu Nov 22 13:24:28 2018 +0100
     1.3 @@ -5,12 +5,15 @@
     1.4  #include "message_api.h"
     1.5  
     1.6  PEP_STATUS base_decorate_message(
     1.7 +        PEP_SESSION session,
     1.8          message *msg,
     1.9          char *payload,
    1.10          size_t size,
    1.11          char *fpr
    1.12      )
    1.13  {
    1.14 +    PEP_STATUS status = PEP_STATUS_OK;
    1.15 +
    1.16      assert(msg);
    1.17      assert(payload);
    1.18      assert(size);
    1.19 @@ -24,17 +27,31 @@
    1.20          goto enomem;
    1.21  
    1.22      if (fpr) {
    1.23 -        // add signature
    1.24 +        char *sign;
    1.25 +        size_t sign_size;
    1.26 +        status = sign_only(session,  payload, size, fpr, &sign, &sign_size);
    1.27 +        if (status)
    1.28 +            goto error;
    1.29 +
    1.30 +        assert(sign && sign_size);
    1.31 +
    1.32 +        bl = bloblist_add(bl, sign, sign_size,
    1.33 +                "application/pEp.sign", "ignore_this_attachment.pEp");
    1.34 +        if (!bl)
    1.35 +            goto enomem;
    1.36      }
    1.37  
    1.38 -    msg->attachments = bl;
    1.39      return PEP_STATUS_OK;
    1.40  
    1.41  enomem:
    1.42 -    return PEP_OUT_OF_MEMORY;
    1.43 +    status = PEP_OUT_OF_MEMORY;
    1.44 +
    1.45 +error:
    1.46 +    return status;
    1.47  }
    1.48  
    1.49  PEP_STATUS base_prepare_message(
    1.50 +        PEP_SESSION session,
    1.51          const pEp_identity *me,
    1.52          const pEp_identity *partner,
    1.53          char *payload,
    1.54 @@ -81,7 +98,7 @@
    1.55      if (!msg->longmsg)
    1.56          goto enomem;
    1.57  
    1.58 -    status = base_decorate_message(msg, payload, size, fpr);
    1.59 +    status = base_decorate_message(session, msg, payload, size, fpr);
    1.60      if (status == PEP_STATUS_OK)
    1.61          *result = msg;
    1.62      return status;
    1.63 @@ -91,25 +108,77 @@
    1.64      return PEP_OUT_OF_MEMORY;
    1.65  }
    1.66  
    1.67 -PEP_STATUS base_extract_message(message *msg, size_t *size, const char **payload)
    1.68 +PEP_STATUS base_extract_message(
    1.69 +        PEP_SESSION session,
    1.70 +        message *msg,
    1.71 +        size_t *size,
    1.72 +        const char **payload,
    1.73 +        char **fpr
    1.74 +    )
    1.75  {
    1.76      PEP_STATUS status = PEP_STATUS_OK;
    1.77  
    1.78 -    assert(msg && size && payload);
    1.79 -    if (!(msg && size && payload))
    1.80 +    assert(session && msg && size && payload && fpr);
    1.81 +    if (!(session && msg && size && payload && fpr))
    1.82          return PEP_ILLEGAL_VALUE;
    1.83  
    1.84      *size = 0;
    1.85      *payload = NULL;
    1.86  
    1.87 +    const char *_payload = NULL;
    1.88 +    size_t _payload_size = 0;
    1.89 +    const char *_sign = NULL;
    1.90 +    size_t _sign_size = 0;
    1.91 +    stringlist_t *keylist = NULL;
    1.92 +
    1.93      for (bloblist_t *bl = msg->attachments; bl ; bl = bl->next) {
    1.94          if (bl->mime_type && strcasecmp(bl->mime_type, "application/pEp.sync") == 0) {
    1.95 -            *size = bl->size;
    1.96 -            *payload = bl->value;
    1.97 -            break;
    1.98 +            if (!_payload) {
    1.99 +                _payload = bl->value;
   1.100 +                _payload_size = bl->size;
   1.101 +            }
   1.102 +            else {
   1.103 +                status = PEP_DECRYPT_WRONG_FORMAT;
   1.104 +                goto the_end;
   1.105 +            }
   1.106 +        }
   1.107 +        else if (bl->mime_type && strcasecmp(bl->mime_type, "application/pEp.sign") == 0) {
   1.108 +            if (!_sign) {
   1.109 +                _sign = bl->value;
   1.110 +                _sign_size = bl->size;
   1.111 +            }
   1.112 +            else {
   1.113 +                status = PEP_DECRYPT_WRONG_FORMAT;
   1.114 +                goto the_end;
   1.115 +            }
   1.116 +        }
   1.117 +    }
   1.118 +    
   1.119 +    if (!(_payload && _payload_size))
   1.120 +        goto the_end;
   1.121 +
   1.122 +    if (_sign) {
   1.123 +        status = verify_text(session, _payload, _payload_size, _sign, _sign_size, &keylist);
   1.124 +        if (status != PEP_VERIFIED || !keylist || !keylist->value) {
   1.125 +            // signature invalid or does not match; ignore sync message
   1.126 +            status = PEP_STATUS_OK;
   1.127 +            goto the_end;
   1.128 +        }
   1.129 +
   1.130 +        char *_fpr = strdup(keylist->value);
   1.131 +        assert(_fpr);
   1.132 +        if (!_fpr) {
   1.133 +            status = PEP_OUT_OF_MEMORY;
   1.134 +            goto the_end;
   1.135          }
   1.136      }
   1.137  
   1.138 +    *size = _payload_size;
   1.139 +    *payload = _payload;
   1.140 +    status = PEP_STATUS_OK;
   1.141 +
   1.142 +the_end:
   1.143 +    free_stringlist(keylist);
   1.144      return status;
   1.145  }
   1.146  
     2.1 --- a/src/baseprotocol.h	Thu Nov 22 13:23:26 2018 +0100
     2.2 +++ b/src/baseprotocol.h	Thu Nov 22 13:24:28 2018 +0100
     2.3 @@ -13,6 +13,7 @@
     2.4  // base_decorate_message() - decorate a message with payload
     2.5  //
     2.6  //  parameters:
     2.7 +//      session (in)    session handle
     2.8  //      msg (inout)     message to decorate
     2.9  //      payload (in)    payload to send
    2.10  //      size (in)       size of payload
    2.11 @@ -26,6 +27,7 @@
    2.12  //      the ownership of the msg remains with the caller
    2.13  
    2.14  PEP_STATUS base_decorate_message(
    2.15 +        PEP_SESSION session,
    2.16          message *msg,
    2.17          char *payload,
    2.18          size_t size,
    2.19 @@ -36,6 +38,7 @@
    2.20  // base_prepare_message() - prepare a sync message with payload
    2.21  //
    2.22  //  parameters:
    2.23 +//      session (in)    session handle
    2.24  //      me (in)         identity to use for the sender
    2.25  //      partner (in)    identity to use for the receiver
    2.26  //      payload (in)    payload to send
    2.27 @@ -51,6 +54,7 @@
    2.28  //      the ownership of the result goes to the caller
    2.29  
    2.30  PEP_STATUS base_prepare_message(
    2.31 +        PEP_SESSION session,
    2.32          const pEp_identity *me,
    2.33          const pEp_identity *partner,
    2.34          char *payload,
    2.35 @@ -63,9 +67,12 @@
    2.36  // base_extract_message() - extract a sync message from a pEp message
    2.37  //
    2.38  //  parameters:
    2.39 +//      session (in)    session handle
    2.40  //      msg (in)        message to analyze
    2.41  //      size (out)      size of extracted payload or 0 if not found
    2.42  //      payload (out)   extraced payload
    2.43 +//      fpr (out)       if message was correctly signed then fpr of signature's
    2.44 +//                      key, otherwise NULL
    2.45  //
    2.46  //  returns:
    2.47  //      PEP_STATUS_OK and payload == NULL if no sync message
    2.48 @@ -74,8 +81,15 @@
    2.49  //
    2.50  //  caveat:
    2.51  //      payload may point to msg attachment, the ownership does not change
    2.52 +//      if fpr != NULL the ownership goes to the caller
    2.53  
    2.54 -PEP_STATUS base_extract_message(message *msg, size_t *size, const char **payload);
    2.55 +PEP_STATUS base_extract_message(
    2.56 +        PEP_SESSION session,
    2.57 +        message *msg,
    2.58 +        size_t *size,
    2.59 +        const char **payload,
    2.60 +        char **fpr
    2.61 +    );
    2.62  
    2.63  
    2.64  #ifdef __cplusplus
     3.1 --- a/src/message_api.c	Thu Nov 22 13:23:26 2018 +0100
     3.2 +++ b/src/message_api.c	Thu Nov 22 13:24:28 2018 +0100
     3.3 @@ -3749,16 +3749,29 @@
     3.4      if (!(session && src && dst && keylist && rating && flags))
     3.5          return PEP_ILLEGAL_VALUE;
     3.6  
     3.7 +    *keylist = NULL;
     3.8      PEP_STATUS status = _decrypt_message(session, src, dst, keylist, rating, flags, NULL);
     3.9  
    3.10      message *msg = *dst ? *dst : src;
    3.11  
    3.12 -    if (session->inject_sync_event && msg) {
    3.13 +    if (session->inject_sync_event && msg && msg->from) {
    3.14          size_t size;
    3.15          const char *data;
    3.16 -        status = base_extract_message(msg, &size, &data);
    3.17 -        if (size && data)
    3.18 -            signal_Sync_message(session, *rating, data, size);
    3.19 +        char *sync_fpr = NULL;
    3.20 +        status = base_extract_message(session, msg, &size, &data, &sync_fpr);
    3.21 +        if (!status && size && data) {
    3.22 +            pEp_identity *_from = identity_dup(msg->from);
    3.23 +            if (!_from) {
    3.24 +                free_message(*dst);
    3.25 +                *dst = NULL;
    3.26 +                free_stringlist(*keylist);
    3.27 +                *keylist = NULL;
    3.28 +                return PEP_OUT_OF_MEMORY;
    3.29 +            }
    3.30 +            memcpy(&session->sync_state.common.from, _from, sizeof(pEp_identity));
    3.31 +            signal_Sync_message(session, *rating, data, size, sync_fpr);
    3.32 +        }
    3.33 +        free(sync_fpr);
    3.34      }
    3.35  
    3.36      return status;
     5.1 --- a/sync/gen_statemachine.ysl2	Thu Nov 22 13:23:26 2018 +0100
     5.2 +++ b/sync/gen_statemachine.ysl2	Thu Nov 22 13:24:28 2018 +0100
     5.3 @@ -197,7 +197,8 @@
     5.4                      PEP_SESSION session, 
     5.5                      PEP_rating rating,
     5.6                      const char *data,
     5.7 -                    size_t size
     5.8 +                    size_t size,
     5.9 +                    const char *fpr
    5.10                  );
    5.11  
    5.12              #ifdef __cplusplus
    5.13 @@ -310,7 +311,8 @@
    5.14                      PEP_SESSION session, 
    5.15                      PEP_rating rating,
    5.16                      const char *data,
    5.17 -                    size_t size
    5.18 +                    size_t size,
    5.19 +                    const char *fpr
    5.20                  )
    5.21              {
    5.22                  assert(session && data && size);
    5.23 @@ -337,6 +339,17 @@
    5.24                          goto the_end;
    5.25                  }
    5.26  
    5.27 +                if (fpr) {
    5.28 +                    if (session->«yml:lcase(@name)»_state.common.from->fpr)
    5.29 +                        free(session->«yml:lcase(@name)»_state.common.from->fpr);
    5.30 +                    session->«yml:lcase(@name)»_state.common.from->fpr = strdup(fpr);
    5.31 +                    assert(session->«yml:lcase(@name)»_state.common.from->fpr);
    5.32 +                    if (!session->«yml:lcase(@name)»_state.common.from->fpr) {
    5.33 +                        status = PEP_OUT_OF_MEMORY;
    5.34 +                        goto the_end;
    5.35 +                    }
    5.36 +                }
    5.37 +
    5.38                  ev = new_«@name»_event(fsm, event, msg);
    5.39                  if (!ev) {
    5.40                      status = PEP_OUT_OF_MEMORY;
    5.41 @@ -349,6 +362,7 @@
    5.42                      status = PEP_STATEMACHINE_ERROR;
    5.43                      goto the_end;
    5.44                  }
    5.45 +
    5.46                  return PEP_STATUS_OK;
    5.47  
    5.48              the_end:
    5.49 @@ -455,6 +469,7 @@
    5.50                      switch (message_type) {
    5.51                      `` for "fsm/message[@security='unencrypted']" |>>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
    5.52                              status = base_prepare_message(
    5.53 +                                    session,
    5.54                                      li->ident,
    5.55                                      li->ident,
    5.56                                      _data,
    5.57 @@ -472,6 +487,7 @@
    5.58  
    5.59                          default:
    5.60                              status = base_prepare_message(
    5.61 +                                    session,
    5.62                                      li->ident,
    5.63                                      li->ident,
    5.64                                      _data,
    5.65 @@ -609,10 +625,14 @@
    5.66              switch (event) {
    5.67          ||
    5.68          if "message[@security='unencrypted']" {
    5.69 -            |         // these messages are going untested
    5.70 +            |         // these messages require a detached signature
    5.71              for "message[@security='unencrypted']"
    5.72                  |>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
    5.73              ||
    5.74 +                        if (!fpr) {
    5.75 +                            status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
    5.76 +                            goto the_end;
    5.77 +                        }
    5.78                          break;
    5.79  
    5.80              ||
    5.81 @@ -621,7 +641,7 @@
    5.82          ||
    5.83                  // these messages must arrive encrypted
    5.84          `` for "message[@security='untrusted']" |>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
    5.85 -                    if (rating < PEP_rating_reliable) {
    5.86 +                    if (fpr || rating < PEP_rating_reliable) {
    5.87                          status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
    5.88                          goto the_end;
    5.89                      }
    5.90 @@ -632,7 +652,7 @@
    5.91          ||
    5.92                  // these messages must come through a trusted channel
    5.93          `` for "message[@security='trusted']" |>> case «ancestor::fsm/@name»__payload_PR_«yml:mixedCase(@name)»:
    5.94 -                    if (rating < PEP_rating_trusted) {
    5.95 +                    if (fpr || rating < PEP_rating_trusted) {
    5.96                          status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
    5.97                          goto the_end;
    5.98                      }