X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-session.c;h=fe5aa4afbb244445a27b50457ef09f6b3693ca1d;hb=29ae81fa15c6080fd27929f4cc78e1289cb920e9;hp=19a5ebfcfc768b85418d5c2c0f63e8b4a6557d9f;hpb=043c27c3a8fd323d59e41288b6fd24f0e9bfa9a3;p=src%2Fapp-framework-binder.git diff --git a/src/afb-session.c b/src/afb-session.c index 19a5ebfc..fe5aa4af 100644 --- a/src/afb-session.c +++ b/src/afb-session.c @@ -24,16 +24,15 @@ #include #include #include -#include #include -#include #include "afb-session.h" #include "afb-hook.h" +#include "afb-token.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 +68,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 */ + struct afb_token *token;/**< short term authentication of remote client */ }; /** @@ -81,14 +80,14 @@ 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 */ + struct afb_token *initok;/**< common initial token */ pthread_mutex_t mutex; /**< declare a mutex to protect hash table */ } sessions = { .count = 0, .max = 10, .timeout = 3600, .heads = { 0 }, - .initok = { 0 }, + .initok = 0, .mutex = PTHREAD_MUTEX_INITIALIZER }; @@ -102,65 +101,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 +146,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; @@ -240,8 +180,10 @@ static void session_close(struct afb_session *session) /* close it now */ session->closed = 1; +#if WITH_AFB_HOOK /* emit the hook */ afb_hook_session_close(session); +#endif /* release cookies */ for (idx = 0 ; idx < COOKIECOUNT ; idx++) { @@ -258,8 +200,11 @@ static void session_close(struct afb_session *session) /* destroy the 'session' */ static void session_destroy (struct afb_session *session) { +#if WITH_AFB_HOOK afb_hook_session_destroy(session); +#endif pthread_mutex_destroy(&session->mutex); + afb_token_unref(session->token); free(session->lang); free(session); } @@ -306,17 +251,20 @@ static struct afb_session *session_add(const char *uuid, int timeout, time_t now pthread_mutex_init(&session->mutex, NULL); session->refcount = 1; strcpy(session->uuid, uuid); - strcpy(session->token, sessions.initok); + session->token = afb_token_addref(sessions.initok); session->timeout = timeout; session_update_expiration(session, now); /* add */ if (sessionset_add(session, hashidx)) { + afb_token_unref(session->token); free(session); return NULL; } +#if WITH_AFB_HOOK afb_hook_session_create(session); +#endif return session; } @@ -364,6 +312,9 @@ static time_t sessionset_cleanup (int force) */ int afb_session_init (int max_session_count, int timeout, const char *initok) { + int rc; + uuid_stringz_t uuid; + /* check parameters */ if (initok && strlen(initok) >= sizeof sessions.initok) { ERROR("initial token '%s' too long (max length %d)", @@ -377,10 +328,16 @@ int afb_session_init (int max_session_count, int timeout, const char *initok) sessionset_cleanup(1); sessions.max = max_session_count; sessions.timeout = timeout; - if (initok == NULL) - new_uuid(sessions.initok); - else - strcpy(sessions.initok, initok); + if (initok == NULL) { + uuid_new_stringz(uuid); + initok = uuid; + } + sessions.initok = 0; + if (*initok) { + rc = afb_token_get(&sessions.initok, initok); + if (rc < 0) + return rc; + } sessionset_unlock(); return 0; } @@ -422,7 +379,7 @@ void afb_session_purge() */ const char *afb_session_initial_token() { - return sessions.initok; + return sessions.initok ? afb_token_string(sessions.initok) : ""; } /* Searchs the session of 'uuid' */ @@ -474,7 +431,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; @@ -513,7 +470,9 @@ end: struct afb_session *afb_session_addref(struct afb_session *session) { if (session != NULL) { +#if WITH_AFB_HOOK afb_hook_session_addref(session); +#endif session_lock(session); session->refcount++; session_unlock(session); @@ -527,7 +486,9 @@ void afb_session_unref(struct afb_session *session) if (session == NULL) return; +#if WITH_AFB_HOOK afb_hook_session_unref(session); +#endif session_lock(session); if (!--session->refcount) { if (session->autoclose) @@ -579,7 +540,7 @@ int afb_session_check_token (struct afb_session *session, const char *token) session_lock(session); r = !session->closed && session->expiration >= NOW - && !(session->token[0] && strcmp (token, session->token)); + && !(session->token && strcmp(token, afb_session_token(session))); session_unlock(session); return r; } @@ -587,10 +548,23 @@ int afb_session_check_token (struct afb_session *session, const char *token) /* generate a new token and update client context */ void afb_session_new_token (struct afb_session *session) { + int rc; + uuid_stringz_t uuid; + struct afb_token *previous, *next; session_lock(session); - new_uuid(session->token); - session_update_expiration(session, NOW); - afb_hook_session_renew(session); + uuid_new_stringz(uuid); + rc = afb_token_get(&next, uuid); + if (rc < 0) + ERROR("can't renew token"); + else { + previous = session->token; + session->token = next; + session_update_expiration(session, NOW); +#if WITH_AFB_HOOK + afb_hook_session_renew(session); +#endif + afb_token_unref(previous); + } session_unlock(session); } @@ -603,7 +577,7 @@ const char *afb_session_uuid (struct afb_session *session) /* Returns the token of 'session' */ const char *afb_session_token (struct afb_session *session) { - return session->token; + return afb_token_string(session->token); } /** @@ -628,7 +602,7 @@ static int cookeyidx(const void *key) * @param makecb the creation function or NULL * @param freecb the release function or NULL * @param closure an argument for makecb or the value if makecb==NULL - * @param replace a boolean enforcing replecement of the previous value + * @param replace a boolean enforcing replacement of the previous value * * @return the value of the cookie *