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