diff options
author | José Bollo <jose.bollo@iot.bzh> | 2019-07-16 15:27:29 +0200 |
---|---|---|
committer | Jose Bollo <jose.bollo@iot.bzh> | 2019-07-18 15:39:52 +0200 |
commit | c53b1b3433a9fcb0f4f3afe8eca1daf75d43673f (patch) | |
tree | 69c16c2b0f38542d6cce3ba30648f7b62f4a9b87 | |
parent | 328c4b574dfb30155b8e27d96d97a1a50b51ebb8 (diff) |
uuid: Add module for UUID generation
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
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Change-Id: I20b58cf074ca88994de049acbeb8f827359e1b69
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/afb-session.c | 79 | ||||
-rw-r--r-- | src/uuid.c | 88 | ||||
-rw-r--r-- | src/uuid.h | 27 |
4 files changed, 125 insertions, 70 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d81c314e..4f5c269e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,6 +74,7 @@ SET(AFB_LIB_SOURCES process-name.c sig-monitor.c subpath.c + uuid.c verbose.c websock.c wrap-json.c diff --git a/src/afb-session.c b/src/afb-session.c index 2cfbff99..eb34046e 100644 --- a/src/afb-session.c +++ b/src/afb-session.c @@ -24,16 +24,14 @@ #include <stdint.h> #include <limits.h> #include <string.h> -#include <uuid/uuid.h> #include <errno.h> -#include <unistd.h> #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; @@ -378,7 +317,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(); @@ -474,7 +413,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; @@ -588,7 +527,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); afb_hook_session_renew(session); session_unlock(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 <jose.bollo@iot.bzh> + * + * 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 <stdint.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> + +#include <uuid/uuid.h> + +#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 <jose.bollo@iot.bzh> + * + * 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); |