diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ad9918..56bfb6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ SET (DEP_LIBS -ldl -ljson-glib-1.0 -lgobject-2.0 + -luuid ) # JSON-GLIB @@ -124,6 +125,7 @@ ADD_EXECUTABLE (${PROJECT_NAME} ${UTILS_DIR}/library.c ${UTILS_DIR}/logger.c ${UTILS_DIR}/str_t.c + ${UTILS_DIR}/uuid.c ${FCGISRV_DIR}/fcgi_map.c ${FCGISRV_DIR}/fcgi_server.c ${FCGISRV_DIR}/fcgi_thread.c diff --git a/src/utils/uuid.c b/src/utils/uuid.c new file mode 100644 index 0000000..21149c9 --- /dev/null +++ b/src/utils/uuid.c @@ -0,0 +1,116 @@ +#include "uuid.h" + +#include "cryptopro.h" +#include "logger.h" + +#include +#include +#include + +struct uuid { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint16_t clock_seq; + uint8_t node[6]; +}; + +static void +uuid_unpack(const uuid_t in, struct uuid *uu) +{ + const uint8_t *ptr = in; + uint32_t tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_low = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_mid = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_hi_and_version = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->clock_seq = tmp; + + memcpy(uu->node, ptr, 6); +} + +static void +uuid_pack(const struct uuid *uu, uuid_t ptr) +{ + uint32_t tmp; + unsigned char *out = ptr; + + tmp = uu->time_low; + out[3] = (unsigned char) tmp; + tmp >>= 8; + out[2] = (unsigned char) tmp; + tmp >>= 8; + out[1] = (unsigned char) tmp; + tmp >>= 8; + out[0] = (unsigned char) tmp; + + tmp = uu->time_mid; + out[5] = (unsigned char) tmp; + tmp >>= 8; + out[4] = (unsigned char) tmp; + + tmp = uu->time_hi_and_version; + out[7] = (unsigned char) tmp; + tmp >>= 8; + out[6] = (unsigned char) tmp; + + tmp = uu->clock_seq; + out[9] = (unsigned char) tmp; + tmp >>= 8; + out[8] = (unsigned char) tmp; + + memcpy(out+10, uu->node, 6); +} + +char* +generate_uuid4() +{ + char *uuid; + uuid_t buf; + uuid_t out; + struct uuid uu; + + LOG_TRACE("generate_uuid enter"); + + uuid = malloc(UUID_STR_LEN); + if (uuid == NULL) { + LOG_ERROR("Could not allocate memory fot uuid (%d bytes)", UUID_STR_LEN); + goto error; + } + + if (cryptopro_gen_random(buf, sizeof(buf))) { + goto error; + } + + uuid_unpack(buf, &uu); + + uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000; + uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000; + + uuid_pack(&uu, out); + + LOG_DEBUG("uuid_type: %d, uuid_variant: %d", uuid_type(out), uuid_variant(out)); + + uuid_unparse(out, uuid); + + LOG_TRACE("generate_uuid exit"); + return uuid; + +error: + free(uuid); + LOG_ERROR("generate_uuid exit with error"); + return NULL; +} diff --git a/src/utils/uuid.h b/src/utils/uuid.h new file mode 100644 index 0000000..290aa43 --- /dev/null +++ b/src/utils/uuid.h @@ -0,0 +1,7 @@ +#ifndef UUID_H_INCLUDED +#define UUID_H_INCLUDED + +// generates uuid version 4 +char* generate_uuid4(); + +#endif // UUID_H_INCLUDED \ No newline at end of file