src/sync_impl.c
author Volker Birk <vb@pep.foundation>
Tue, 23 Aug 2016 17:35:13 +0200
branchkeysync
changeset 1074 aebf26305436
parent 1073 b5c5c448a1dd
child 1075 6ac3fd936e93
permissions -rw-r--r--
correcting indirection
     1 #include "../asn.1/DeviceGroup-Protocol.h"
     2 #include "sync_impl.h"
     3 #include "pEp_internal.h"
     4 #include "keymanagement.h"
     5 #include "map_asn1.h"
     6 #include "baseprotocol.h"
     7 
     8 PEP_STATUS receive_sync_msg(
     9         PEP_SESSION session,
    10         DeviceGroup_Protocol_t *msg
    11     )
    12 {
    13     assert(session && msg && msg->payload.present != DeviceGroup_Protocol__payload_PR_NOTHING);
    14     if (!(session && msg && msg->payload.present != DeviceGroup_Protocol__payload_PR_NOTHING))
    15         return PEP_ILLEGAL_VALUE;
    16 
    17     void *extra = NULL;
    18     Identity partner = NULL;
    19     DeviceState_event event = DeviceState_event_NONE;
    20 
    21     switch (msg->payload.present) {
    22         case DeviceGroup_Protocol__payload_PR_beacon:
    23             partner = Identity_to_Struct(&msg->header.me, NULL);
    24             if (!partner)
    25                 return PEP_OUT_OF_MEMORY;
    26             event = Beacon;
    27             break;
    28 
    29         case DeviceGroup_Protocol__payload_PR_handshakeRequest:
    30             partner = Identity_to_Struct(
    31                     &msg->header.me, NULL);
    32             if (!partner)
    33                 return PEP_OUT_OF_MEMORY;
    34             event = HandshakeRequest;
    35             break;
    36 
    37         case DeviceGroup_Protocol__payload_PR_groupKeys:
    38             partner = Identity_to_Struct(&msg->header.me,
    39                     NULL);
    40             if (!partner)
    41                 return PEP_OUT_OF_MEMORY;
    42             identity_list *group_keys = IdentityList_to_identity_list(
    43                     &msg->payload.choice.groupKeys.ownIdentities, NULL);
    44             if (!group_keys) {
    45                 free_identity(partner);
    46                 return PEP_OUT_OF_MEMORY;
    47             }
    48             extra = (void *) group_keys;
    49             event = GroupKeys;
    50             break;
    51 
    52         default:
    53             return PEP_SYNC_ILLEGAL_MESSAGE;
    54     }
    55 
    56     return fsm_DeviceState_inject(session, event, partner, extra);
    57 }
    58 
    59 PEP_STATUS receive_DeviceState_msg(PEP_SESSION session, message *src)
    60 {
    61     assert(session && src);
    62     if (!(session && src))
    63         return PEP_ILLEGAL_VALUE;
    64 
    65     bool found = false;
    66 
    67     for (bloblist_t *bl = src->attachments; bl && bl->value; bl = bl->next) {
    68         if (bl->mime_type && strcasecmp(bl->mime_type, "application/pEp") == 0
    69                 && bl->size) {
    70             DeviceGroup_Protocol_t *msg;
    71             uper_decode_complete(NULL, &asn_DEF_DeviceGroup_Protocol,
    72                     (void **) &msg, bl->value, bl->size);
    73             if (msg) {
    74                 found = true;
    75                 PEP_STATUS status = session->inject_sync_msg(msg, session->sync_obj);
    76                 ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
    77                 if (status != PEP_STATUS_OK)
    78                     return status;
    79             }
    80         }
    81     }
    82 
    83     if (found) {
    84         for (stringpair_list_t *spl = src->opt_fields ; spl && spl->value ;
    85                 spl = spl->next) {
    86             if (spl->value->key &&
    87                     strcasecmp(spl->value->key, "pEp-auto-consume") == 0) {
    88                 if (spl->value->value &&
    89                         strcasecmp(spl->value->value, "yes") == 0)
    90                     return PEP_MESSAGE_CONSUMED;
    91             }
    92         }
    93     }
    94 
    95     return PEP_STATUS_OK;
    96 }
    97 
    98 DeviceGroup_Protocol_t *new_DeviceGroup_Protocol_msg(DeviceGroup_Protocol__payload_PR type)
    99 {
   100     DeviceGroup_Protocol_t *msg = (DeviceGroup_Protocol_t *)
   101             calloc(1, sizeof(DeviceGroup_Protocol_t));
   102     assert(msg);
   103     if (!msg)
   104         return NULL;
   105     msg->payload.present = type;
   106     return msg;
   107 }
   108 
   109 void free_DeviceGroup_Protocol_msg(DeviceGroup_Protocol_t *msg)
   110 {
   111     ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   112 }
   113 
   114 PEP_STATUS unicast_msg(
   115         PEP_SESSION session,
   116         Identity partner,
   117         DeviceState_state state,
   118         DeviceGroup_Protocol_t *msg
   119     )
   120 {
   121     PEP_STATUS status = PEP_STATUS_OK;
   122     char *payload = NULL;
   123     message *_message = NULL;
   124     pEp_identity *me = NULL;
   125 
   126     assert(session && partner && state && msg);
   127     if (!(session && partner && state && msg))
   128         return PEP_ILLEGAL_VALUE;
   129 
   130     assert(session->messageToSend);
   131     if (!session->messageToSend) {
   132         status = PEP_SEND_FUNCTION_NOT_REGISTERED;
   133         goto error;
   134     }
   135 
   136     int32_t seq;
   137     status = sequence_value(session, "DeviceGroup", &seq);
   138     if (status != PEP_STATUS_OK)
   139         goto error;
   140     msg->header.sequence = (long) seq;
   141 
   142     bool devicegroup = storedGroupKeys(session);
   143     if (devicegroup) { // default is FALSE
   144         BOOLEAN_t *dg = malloc(sizeof(BOOLEAN_t));
   145         assert(dg);
   146         if (!dg)
   147             goto enomem;
   148 
   149         *dg = 1;
   150         msg->header.devicegroup = dg;
   151     }
   152 
   153     msg->header.state = (long) state;
   154 
   155     status = get_identity(session, partner->address, PEP_OWN_USERID, &me);
   156     if (status != PEP_STATUS_OK)
   157         goto error;
   158     if (Identity_from_Struct(me, &msg->header.me) == NULL)
   159         goto enomem;
   160 
   161     if (asn_check_constraints(&asn_DEF_DeviceGroup_Protocol, msg, NULL, NULL)) {
   162         status = PEP_CONTRAINTS_VIOLATED;
   163         goto error;
   164     }
   165 
   166     ssize_t size = uper_encode_to_new_buffer(&asn_DEF_DeviceGroup_Protocol,
   167             NULL, msg, (void **) &payload);
   168     if (size == -1) {
   169         status = PEP_CANNOT_ENCODE;
   170         goto error;
   171     }
   172 
   173     status = prepare_message(me, partner, payload, size, &_message);
   174     if (status != PEP_STATUS_OK)
   175         goto error;
   176     payload = NULL;
   177 
   178     free_identity(me);
   179     me = NULL;
   180 
   181     status = session->messageToSend(session->sync_obj, _message);
   182 
   183     free_identity(partner);
   184     return status;
   185 
   186 enomem:
   187     status = PEP_OUT_OF_MEMORY;
   188 error:
   189     free(payload);
   190     free_message(_message);
   191     free_identity(me);
   192     free_identity(partner);
   193     return status;
   194 }
   195 
   196 PEP_STATUS multicast_self_msg(
   197         PEP_SESSION session,
   198         DeviceState_state state,
   199         DeviceGroup_Protocol_t *msg
   200     )
   201 {
   202     PEP_STATUS status = PEP_STATUS_OK;
   203 
   204     assert(session && state && msg);
   205     if (!(session && state && msg))
   206         return PEP_ILLEGAL_VALUE;
   207 
   208     identity_list *own_identities = NULL;
   209     status = own_identities_retrieve(session, &own_identities);
   210     if (status != PEP_STATUS_OK)
   211         return status;
   212 
   213     for (identity_list *_i = own_identities; _i && _i->ident; _i = _i->next) {
   214         pEp_identity *me = _i->ident;
   215 
   216         // FIXME: no deep copy for multicast supported yet
   217         DeviceGroup_Protocol_t *_msg = malloc(sizeof(DeviceGroup_Protocol_t));
   218         assert(_msg);
   219         if (_msg == NULL)
   220             goto enomem;
   221         memcpy(_msg, msg, sizeof(DeviceGroup_Protocol_t));
   222         status = unicast_msg(session, me, state, _msg);
   223         free_DeviceGroup_Protocol_msg(_msg);
   224     }
   225 
   226     free_identity_list(own_identities);
   227     return PEP_STATUS_OK;
   228 
   229 enomem:
   230     free_identity_list(own_identities);
   231     return PEP_OUT_OF_MEMORY;
   232 }
   233