From 6fe59e27c0640462f92133106b4d4d52d77683f9 Mon Sep 17 00:00:00 2001 From: José Bollo Date: Tue, 16 Jul 2019 15:27:29 +0200 Subject: uuid: Add module for UUID generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit allow modules of afb-daemon to request UUID. This introduce an abstraction above libuuid for 3 reasons: 1. Using uuid had bad side effect inthe past because it required enought entropy at start time, leading to hanging initialisations in wait for enough entropy. 2. Solving bug SPEC-2625 will require use of UUID. 3. Porting to systems that haven't libuuid is made more easy after that. Bug-AGL: SPEC-2625 Change-Id: I27d8b611946686dea6fab250697afe9b89aac869 Signed-off-by: José Bollo --- src/CMakeLists.txt | 1 + src/afb-session.c | 79 ++++++------------------------------------------ src/uuid.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/uuid.h | 27 +++++++++++++++++ 4 files changed, 125 insertions(+), 70 deletions(-) create mode 100644 src/uuid.c create mode 100644 src/uuid.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3b444a0b..ee0adb44 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -123,6 +123,7 @@ SET(AFB_LIB_SOURCES sig-monitor.c subpath.c systemd.c + uuid.c verbose.c watchdog.c websock.c diff --git a/src/afb-session.c b/src/afb-session.c index 70e8c3cd..1bdb59db 100644 --- a/src/afb-session.c +++ b/src/afb-session.c @@ -24,16 +24,14 @@ #include #include #include -#include #include -#include #include "afb-session.h" #include "afb-hook.h" #include "verbose.h" #include "pearson.h" +#include "uuid.h" -#define SIZEUUID 37 #define HEADCOUNT 16 #define COOKIECOUNT 8 #define COOKIEMASK (COOKIECOUNT - 1) @@ -69,8 +67,8 @@ struct afb_session uint8_t closed: 1; /**< is the session closed ? */ uint8_t autoclose: 1; /**< close the session when unreferenced */ uint8_t notinset: 1; /**< session removed from the set of sessions */ - char uuid[SIZEUUID]; /**< long term authentication of remote client */ - char token[SIZEUUID]; /**< short term authentication of remote client */ + uuid_stringz_t uuid; /**< long term authentication of remote client */ + uuid_stringz_t token; /**< short term authentication of remote client */ }; /** @@ -81,7 +79,7 @@ static struct { int max; /**< maximum count of sessions */ int timeout; /**< common initial timeout */ struct afb_session *heads[HEADCOUNT]; /**< sessions */ - char initok[SIZEUUID]; /**< common initial token */ + uuid_stringz_t initok; /**< common initial token */ pthread_mutex_t mutex; /**< declare a mutex to protect hash table */ } sessions = { .count = 0, @@ -102,65 +100,6 @@ static inline time_t time_now() return ts.tv_sec; } -/** - * generate a new fresh 'uuid' - */ -static void new_uuid(char uuid[SIZEUUID]) -{ - uuid_t newuuid; - -#if defined(USE_UUID_GENERATE) - uuid_generate(newuuid); -#else - struct timespec ts; - static uint16_t pid; - static uint16_t counter; - static char state[32]; - static struct random_data rdata; - - int32_t x; - clock_gettime(CLOCK_MONOTONIC_RAW, &ts); - if (pid == 0) { - pid = (uint16_t)getpid(); - counter = (uint16_t)(ts.tv_nsec >> 8); - rdata.state = NULL; - initstate_r((((unsigned)pid) << 16) + ((unsigned)counter), - state, sizeof state, &rdata); - } - ts.tv_nsec ^= (long)ts.tv_sec; - if (++counter == 0) - counter = 1; - - newuuid[0] = (char)(ts.tv_nsec >> 24); - newuuid[1] = (char)(ts.tv_nsec >> 16); - newuuid[2] = (char)(ts.tv_nsec >> 8); - newuuid[3] = (char)(ts.tv_nsec); - - newuuid[4] = (char)(pid >> 8); - newuuid[5] = (char)(pid); - - random_r(&rdata, &x); - newuuid[6] = (char)(((x >> 16) & 0x0f) | 0x40); /* pseudo-random version */ - newuuid[7] = (char)(x >> 8); - - random_r(&rdata, &x); - newuuid[8] = (char)(((x >> 16) & 0x3f) | 0x80); /* variant RFC4122 */ - newuuid[9] = (char)(x >> 8); - - random_r(&rdata, &x); - newuuid[10] = (char)(x >> 16); - newuuid[11] = (char)(x >> 8); - - random_r(&rdata, &x); - newuuid[12] = (char)(x >> 16); - newuuid[13] = (char)(x >> 8); - - newuuid[14] = (char)(counter >> 8); - newuuid[15] = (char)(counter); -#endif - uuid_unparse_lower(newuuid, uuid); -} - /* lock the set of sessions for exclusive access */ static inline void sessionset_lock() { @@ -206,12 +145,12 @@ static int sessionset_add(struct afb_session *session, uint8_t hashidx) } /* make a new uuid not used in the set of sessions */ -static uint8_t sessionset_make_uuid (char uuid[SIZEUUID]) +static uint8_t sessionset_make_uuid (uuid_stringz_t uuid) { uint8_t hashidx; do { - new_uuid(uuid); + uuid_new_stringz(uuid); hashidx = pearson4(uuid); } while(sessionset_search(uuid, hashidx)); return hashidx; @@ -384,7 +323,7 @@ int afb_session_init (int max_session_count, int timeout, const char *initok) sessions.max = max_session_count; sessions.timeout = timeout; if (initok == NULL) - new_uuid(sessions.initok); + uuid_new_stringz(sessions.initok); else strcpy(sessions.initok, initok); sessionset_unlock(); @@ -480,7 +419,7 @@ int afb_session_what_remains(struct afb_session *session) /* This function will return exiting session or newly created session */ struct afb_session *afb_session_get (const char *uuid, int timeout, int *created) { - char _uuid_[SIZEUUID]; + uuid_stringz_t _uuid_; uint8_t hashidx; struct afb_session *session; time_t now; @@ -598,7 +537,7 @@ int afb_session_check_token (struct afb_session *session, const char *token) void afb_session_new_token (struct afb_session *session) { session_lock(session); - new_uuid(session->token); + uuid_new_stringz(session->token); session_update_expiration(session, NOW); #if WITH_AFB_HOOK afb_hook_session_renew(session); diff --git a/src/uuid.c b/src/uuid.c new file mode 100644 index 00000000..c682080f --- /dev/null +++ b/src/uuid.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016-2019 "IoT.bzh" + * Author: José Bollo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include + +#include "uuid.h" + +/** + * generate a new fresh 'uuid' + */ +void uuid_new_binary(uuid_binary_t uuid) +{ +#if defined(USE_UUID_GENERATE) + uuid_generate(uuid); +#else + struct timespec ts; + static uint16_t pid; + static uint16_t counter; + static char state[32]; + static struct random_data rdata; + + int32_t x; + clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + if (pid == 0) { + pid = (uint16_t)getpid(); + counter = (uint16_t)(ts.tv_nsec >> 8); + rdata.state = NULL; + initstate_r((((unsigned)pid) << 16) + ((unsigned)counter), + state, sizeof state, &rdata); + } + ts.tv_nsec ^= (long)ts.tv_sec; + if (++counter == 0) + counter = 1; + + uuid[0] = (char)(ts.tv_nsec >> 24); + uuid[1] = (char)(ts.tv_nsec >> 16); + uuid[2] = (char)(ts.tv_nsec >> 8); + uuid[3] = (char)(ts.tv_nsec); + + uuid[4] = (char)(pid >> 8); + uuid[5] = (char)(pid); + + random_r(&rdata, &x); + uuid[6] = (char)(((x >> 16) & 0x0f) | 0x40); /* pseudo-random version */ + uuid[7] = (char)(x >> 8); + + random_r(&rdata, &x); + uuid[8] = (char)(((x >> 16) & 0x3f) | 0x80); /* variant RFC4122 */ + uuid[9] = (char)(x >> 8); + + random_r(&rdata, &x); + uuid[10] = (char)(x >> 16); + uuid[11] = (char)(x >> 8); + + random_r(&rdata, &x); + uuid[12] = (char)(x >> 16); + uuid[13] = (char)(x >> 8); + + uuid[14] = (char)(counter >> 8); + uuid[15] = (char)(counter); +#endif +} + +void uuid_new_stringz(uuid_stringz_t uuid) +{ + uuid_t newuuid; + uuid_new_binary(newuuid); + uuid_unparse_lower(newuuid, uuid); +} diff --git a/src/uuid.h b/src/uuid.h new file mode 100644 index 00000000..ee467d14 --- /dev/null +++ b/src/uuid.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2016-2019 "IoT.bzh" + * Author: José Bollo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#define UUID_BINARY_LENGTH 16 +#define UUID_STRINGZ_LENGTH 37 + +typedef unsigned char uuid_binary_t[UUID_BINARY_LENGTH]; +typedef char uuid_stringz_t[UUID_STRINGZ_LENGTH]; + +void uuid_new_binary(uuid_binary_t uuid); +void uuid_new_stringz(uuid_stringz_t uuid); -- cgit 1.2.3-korg