src/keymanagement.c
author vb
Fri, 11 Jul 2014 17:43:11 +0200
changeset 8 26cc9f0228f4
parent 0 16f27efbef98
child 10 ead888e73384
permissions -rw-r--r--
moving functionality into pEpEngine
     1 #ifndef WIN32 // UNIX
     2 #define _POSIX_C_SOURCE 200809L
     3 #else
     4 #include "platform_windows.h"
     5 #endif
     6 
     7 #include <string.h>
     8 #include <stdio.h>
     9 #include <stdlib.h>
    10 #include <assert.h>
    11 
    12 #define _EXPORT_PEP_ENGINE_DLL
    13 #include "pEpEngine.h"
    14 #include "keymanagement.h"
    15 
    16 #ifndef MIN
    17 #define MIN(A, B) ((B) > (A) ? (A) : (B))
    18 #endif
    19 
    20 #ifndef EMPTY
    21 #define EMPTY(STR) ((STR == NULL) || (STR)[0] == 0)
    22 #endif
    23 
    24 DYNAMIC_API PEP_STATUS update_identity(
    25         PEP_SESSION session, pEp_identity * identity
    26     )
    27 {
    28     pEp_identity *stored_identity;
    29     PEP_STATUS status;
    30 
    31     assert(session);
    32     assert(identity);
    33     assert(identity->address);
    34 
    35     status = get_identity(session, identity->address, &stored_identity);
    36     assert(status != PEP_OUT_OF_MEMORY);
    37     if (status == PEP_OUT_OF_MEMORY)
    38         return PEP_OUT_OF_MEMORY;
    39 
    40     if (stored_identity) {
    41         if (EMPTY(identity->fpr)) {
    42             identity->comm_type = PEP_ct_unknown;
    43 
    44             stringlist_t *keylist;
    45 
    46             status = find_keys(session, stored_identity->fpr, &keylist);
    47             assert(status != PEP_OUT_OF_MEMORY);
    48             if (status == PEP_OUT_OF_MEMORY)
    49                 return PEP_OUT_OF_MEMORY;
    50 
    51             if (keylist && keylist->value) {
    52                 identity->comm_type = stored_identity->comm_type;
    53             }
    54 
    55             free_stringlist(keylist);
    56 
    57             identity->fpr = strdup(stored_identity->fpr);
    58             assert(identity->fpr);
    59             if (identity->fpr == NULL)
    60                 return PEP_OUT_OF_MEMORY;
    61             identity->fpr_size = stored_identity->address_size;
    62         }
    63         else /* !EMPTY(identity->fpr) */ {
    64             stringlist_t *keylist;
    65 
    66             status = find_keys(session, identity->fpr, &keylist);
    67             assert(status != PEP_OUT_OF_MEMORY);
    68             if (status == PEP_OUT_OF_MEMORY)
    69                 return PEP_OUT_OF_MEMORY;
    70 
    71             if (keylist && keylist->value) {
    72                 if (identity->comm_type == PEP_ct_unknown) {
    73                     if (strcmp(identity->fpr, stored_identity->fpr) == 0) {
    74                         identity->comm_type = stored_identity->comm_type;
    75                     }
    76                     else {
    77                         status = get_trust(session, identity);
    78                         assert(status != PEP_OUT_OF_MEMORY);
    79                         if (status == PEP_OUT_OF_MEMORY)
    80                             return PEP_OUT_OF_MEMORY;
    81                     }
    82                 }
    83             }
    84             else
    85                 identity->comm_type = PEP_ct_unknown;
    86 
    87             free_stringlist(keylist);
    88         }
    89 
    90         if (EMPTY(identity->username)) {
    91             free(identity->username);
    92             identity->username = strdup(stored_identity->username);
    93             assert(identity->username);
    94             if (identity->username == NULL)
    95                 return PEP_OUT_OF_MEMORY;
    96             identity->username_size = stored_identity->username_size;
    97         }
    98 
    99         if (EMPTY(identity->user_id)) {
   100             free(identity->user_id);
   101             identity->user_id = strdup(stored_identity->user_id);
   102             assert(identity->user_id);
   103             if (identity->user_id == NULL)
   104                 return PEP_OUT_OF_MEMORY;
   105             identity->user_id_size = stored_identity->user_id_size;
   106         }
   107 
   108         if (identity->lang[0] == 0) {
   109             identity->lang[0] = stored_identity->lang[0];
   110             identity->lang[1] = stored_identity->lang[1];
   111             identity->lang[2] = 0;
   112         }
   113     }
   114     else /* stored_identity == NULL */ {
   115         if (identity->fpr && identity->user_id) {
   116             if (identity->comm_type == PEP_ct_unknown) {
   117                 status = get_trust(session, identity);
   118                 assert(status != PEP_OUT_OF_MEMORY);
   119                 if (status == PEP_OUT_OF_MEMORY)
   120                     return PEP_OUT_OF_MEMORY;
   121             }
   122             if (identity->comm_type != PEP_ct_unknown && EMPTY(identity->username)) {
   123                 free(identity->username);
   124                 identity->username = strdup("anonymous");
   125                 identity->username_size = 10;
   126             }
   127         }
   128         else
   129             identity->comm_type = PEP_ct_unknown;
   130     }
   131 
   132     status = PEP_STATUS_OK;
   133 
   134     if (identity->comm_type != PEP_ct_unknown) {
   135         status = set_identity(session, identity);
   136         assert(status == PEP_STATUS_OK);
   137     }
   138 
   139     return status;
   140 }
   141 
   142 DYNAMIC_API PEP_STATUS outgoing_comm_type(
   143         PEP_SESSION session,
   144         const stringlist_t *addresses,
   145         PEP_comm_type *comm_type
   146     )
   147 {
   148     const stringlist_t *l;
   149 
   150     assert(session);
   151     assert(addresses);
   152     assert(addresses->value);
   153     assert(comm_type);
   154 
   155     *comm_type = PEP_ct_unknown;
   156 
   157     for (l=addresses; l && l->value; l = l->next) {
   158         PEP_STATUS _status;
   159         pEp_identity *identity;
   160 
   161         _status = get_identity(session, l->value, &identity);
   162         assert(_status != PEP_OUT_OF_MEMORY);
   163 
   164         if (identity == NULL) {
   165             *comm_type = PEP_ct_no_encryption;
   166             return PEP_STATUS_OK;
   167         }
   168         else if (identity->comm_type == PEP_ct_unknown) {
   169             *comm_type = PEP_ct_no_encryption;
   170             free_identity(identity);
   171             return PEP_STATUS_OK;
   172         }
   173         else if (*comm_type == PEP_ct_unknown) {
   174             *comm_type = identity->comm_type;
   175         }
   176         else if (*comm_type != identity->comm_type) {
   177             PEP_comm_type min = MIN(*comm_type, identity->comm_type);
   178             if (min < PEP_ct_unconfirmed_encryption) {
   179                 *comm_type = PEP_ct_no_encryption;
   180                 free_identity(identity);
   181                 return PEP_STATUS_OK;
   182             }
   183             else if (min < PEP_ct_unconfirmed_enc_anon)
   184                 *comm_type = PEP_ct_unconfirmed_encryption;
   185             else if (min < PEP_ct_confirmed_encryption)
   186                 *comm_type = PEP_ct_unconfirmed_enc_anon;
   187             else if (min < PEP_ct_confirmed_enc_anon)
   188                 *comm_type = PEP_ct_confirmed_encryption;
   189             else
   190                 *comm_type = PEP_ct_confirmed_enc_anon;
   191         }
   192 
   193         free_identity(identity);
   194     }
   195 
   196     return PEP_STATUS_OK;
   197 }
   198 
   199 DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
   200 {
   201     PEP_STATUS status;
   202     stringlist_t *keylist;
   203 
   204     assert(session);
   205     assert(identity);
   206     assert(identity->address);
   207     assert(identity->username);
   208     assert(identity->user_id);
   209 
   210     identity->comm_type = PEP_ct_pEp;
   211     identity->me = true;
   212 
   213     pEp_identity *_identity;
   214 
   215     log_event(session, "myself", "debug", identity->address, NULL);
   216     status = get_identity(session, identity->address, &_identity);
   217     assert(status != PEP_OUT_OF_MEMORY);
   218     if (status == PEP_OUT_OF_MEMORY)
   219         return PEP_OUT_OF_MEMORY;
   220 
   221     status = find_keys(session, identity->address, &keylist);
   222     assert(status != PEP_OUT_OF_MEMORY);
   223     if (status == PEP_OUT_OF_MEMORY)
   224         return PEP_OUT_OF_MEMORY;
   225 
   226     if (keylist == NULL || keylist->value == NULL) {
   227         log_event(session, "generating key pair", "debug", identity->address, NULL);
   228         status = generate_keypair(session, identity);
   229         assert(status != PEP_OUT_OF_MEMORY);
   230         if (status != PEP_STATUS_OK) {
   231             char buf[11];
   232             snprintf(buf, 11, "%d", status);
   233             log_event(session, "generating key pair failed", "debug", buf, NULL);
   234             return status;
   235         }
   236 
   237         status = find_keys(session, identity->address, &keylist);
   238         assert(status != PEP_OUT_OF_MEMORY);
   239         if (status == PEP_OUT_OF_MEMORY)
   240             return PEP_OUT_OF_MEMORY;
   241 
   242         assert(keylist);
   243     }
   244 
   245     if (identity->fpr)
   246         free(identity->fpr);
   247     identity->fpr = strdup(keylist->value);
   248     assert(identity->fpr);
   249     free_stringlist(keylist);
   250     if (identity->fpr == NULL)
   251         return PEP_OUT_OF_MEMORY;
   252     identity->fpr_size = strlen(identity->fpr);
   253 
   254     status = set_identity(session, identity);
   255     assert(status == PEP_STATUS_OK);
   256 
   257     return PEP_STATUS_OK;
   258 }
   259 
   260 DYNAMIC_API PEP_STATUS do_keymanagement(
   261         retrieve_next_identity_t retrieve_next_identity,
   262         void *management
   263     )
   264 {
   265     PEP_SESSION session;
   266     pEp_identity *identity;
   267     PEP_STATUS status = init(&session);
   268 
   269     assert(status == PEP_STATUS_OK);
   270     if (status != PEP_STATUS_OK)
   271         return status;
   272 
   273     log_event(session, "keymanagement thread started", "pEp engine", NULL, NULL);
   274 
   275     while (identity = retrieve_next_identity(management)) {
   276         assert(identity->address);
   277         log_event(session, "do_keymanagement", "debug", identity->address, NULL);
   278         if (identity->me) {
   279             status = myself(session, identity);
   280             assert(status != PEP_OUT_OF_MEMORY);
   281         } else {
   282             status = recv_key(session, identity->address);
   283             assert(status != PEP_OUT_OF_MEMORY);
   284         }
   285         free_identity(identity);
   286     }
   287 
   288     log_event(session, "keymanagement thread shutdown", "pEp engine", NULL, NULL);
   289 
   290     release(session);
   291     return PEP_STATUS_OK;
   292 }
   293