X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fmeshlink.c;h=b1f5c918fa68dd9d1d29e09a710c60d73b3bd51e;hb=230b5907e242aa48bb8c8d09450fbd3767e9c24a;hp=185f6689af767d6e3ab207816619962ede74e4fe;hpb=1442d234fb6681e32b10348a6c7b226c11629203;p=meshlink diff --git a/src/meshlink.c b/src/meshlink.c index 185f6689..b1f5c918 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1058,19 +1058,82 @@ bool meshlink_open_params_set_storage_key(meshlink_open_params_t *params, const } bool meshlink_encrypted_key_rotate(meshlink_handle_t *mesh, const void *new_key, size_t new_keylen) { + if(!mesh || !new_key || !new_keylen) { + logger(mesh, MESHLINK_ERROR, "Invalid arguments given!\n"); + meshlink_errno = MESHLINK_EINVAL; + return false; + } + + pthread_mutex_lock(&(mesh->mesh_mutex)); + + // Create hash for the new key + void *new_config_key; + new_config_key = xmalloc(CHACHA_POLY1305_KEYLEN); + + if(!prf(new_key, new_keylen, "MeshLink configuration key", 26, new_config_key, CHACHA_POLY1305_KEYLEN)) { + logger(mesh, MESHLINK_ERROR, "Error creating new configuration key!\n"); + meshlink_errno = MESHLINK_EINTERNAL; + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return false; + } + + // Copy contents of the "current" confbase sub-directory to "new" confbase sub-directory with the new key + + if(!config_copy(mesh, "current", mesh->config_key, "new", new_config_key)) { + logger(mesh, MESHLINK_ERROR, "Could not set up configuration in %s/old: %s\n", mesh->confbase, strerror(errno)); + meshlink_errno = MESHLINK_ESTORAGE; + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return false; + } - // While copying old config files to new config files devtool_keyrotate_probe(1); - // After completed creating new config files in confbase/new/ + + main_config_unlock(mesh); + + // Rename confbase/current/ to confbase/old + + if(!config_rename(mesh, "current", "old")) { + logger(mesh, MESHLINK_ERROR, "Cannot rename %s/current to %s/old\n", mesh->confbase, mesh->confbase); + meshlink_errno = MESHLINK_ESTORAGE; + main_config_lock(mesh); + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return false; + } + devtool_keyrotate_probe(2); - // Rename confbase/current to confbase/old/ - devtool_keyrotate_probe(3); + // Rename confbase/new/ to confbase/current - devtool_keyrotate_probe(4); - // Before deleting old sub-directory - devtool_keyrotate_probe(5); - return false; + if(!config_rename(mesh, "new", "current")) { + logger(mesh, MESHLINK_ERROR, "Cannot rename %s/new to %s/current\n", mesh->confbase, mesh->confbase); + meshlink_errno = MESHLINK_ESTORAGE; + main_config_lock(mesh); + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return false; + } + + devtool_keyrotate_probe(3); + + if(!main_config_lock(mesh)) { + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return false; + } + + // Cleanup the "old" confbase sub-directory + + if(!config_destroy(mesh->confbase, "old")) { + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return false; + } + + // Change the mesh handle key with new key + + free(mesh->config_key); + mesh->config_key = new_config_key; + + pthread_mutex_unlock(&(mesh->mesh_mutex)); + + return true; } void meshlink_open_params_free(meshlink_open_params_t *params) { @@ -2247,7 +2310,15 @@ bool meshlink_join(meshlink_handle_t *mesh, const char *invitation) { //Before doing meshlink_join make sure we are not connected to another mesh if(mesh->threadstarted) { - logger(mesh, MESHLINK_DEBUG, "Already connected to a mesh\n"); + logger(mesh, MESHLINK_ERROR, "Cannot join while started\n"); + meshlink_errno = MESHLINK_EINVAL; + pthread_mutex_unlock(&(mesh->mesh_mutex)); + return false; + } + + // Refuse to join a mesh if we are already part of one. We are part of one if we know at least one other node. + if(mesh->nodes->count > 1) { + logger(mesh, MESHLINK_ERROR, "Already part of an existing mesh\n"); meshlink_errno = MESHLINK_EINVAL; pthread_mutex_unlock(&(mesh->mesh_mutex)); return false; @@ -3019,6 +3090,21 @@ end: #endif } +void handle_network_change(meshlink_handle_t *mesh, bool online) { + if(!mesh->connections) { + return; + } + + if(online) { + retry(mesh); + } else { + // We are off-line. Terminate all active connections. + for list_each(connection_t, c, mesh->connections) { + terminate_connection(mesh, c, false); + } + } +} + static void __attribute__((constructor)) meshlink_init(void) { crypto_init(); unsigned int seed;